<?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: Irfan Gulzar</title>
    <description>The latest articles on DEV Community by Irfan Gulzar (@irfangulzarx).</description>
    <link>https://dev.to/irfangulzarx</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%2F3813354%2F595f3bac-c910-4370-b14d-c8fc8f1ecff6.jpg</url>
      <title>DEV Community: Irfan Gulzar</title>
      <link>https://dev.to/irfangulzarx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/irfangulzarx"/>
    <language>en</language>
    <item>
      <title>Your AI Agent Didn't Fail. It Succeeded — Confidently — at the Wrong Thing.</title>
      <dc:creator>Irfan Gulzar</dc:creator>
      <pubDate>Mon, 09 Nov 2026 09:05:23 +0000</pubDate>
      <link>https://dev.to/irfangulzarx/your-ai-agent-didnt-fail-it-succeeded-confidently-at-the-wrong-thing-a1a</link>
      <guid>https://dev.to/irfangulzarx/your-ai-agent-didnt-fail-it-succeeded-confidently-at-the-wrong-thing-a1a</guid>
      <description>&lt;p&gt;The scariest failure mode in automation isn't an error message. It's a green tick on a wrong outcome.&lt;/p&gt;

&lt;p&gt;Last week, Cisco's Outshift team shared a result that should make every engineer building multi-agent systems pause: when they staged debates among five-agent teams, &lt;strong&gt;75% ended with every agent agreeing on the wrong outcome&lt;/strong&gt;. The agents backed off their positions, converged on a consensus — and a cost report would have logged those sessions as efficient, because they burned fewer tokens.&lt;/p&gt;

&lt;p&gt;Fewer tokens. Wrong answer. Everyone agreed. Nobody noticed.&lt;/p&gt;

&lt;p&gt;If you're building AI agents for production, this is the problem that actually matters. Not which model to use. Not which framework. What happens when your agent is wrong and nobody is watching.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agreement is not verification
&lt;/h2&gt;

&lt;p&gt;Multi-agent debate sounds rigorous. One agent makes mistakes, so let five of them argue it out and converge on the truth. The intuition is elegant — and it breaks in a specific, measurable way.&lt;/p&gt;

&lt;p&gt;The mathematical foundation most people assume is the Condorcet Jury Theorem: if every voter is independently more likely right than wrong, the majority gets more accurate as the group grows. But the keyword is &lt;em&gt;independently&lt;/em&gt;. LLM agents are not independent voters. They share training data, share prompts, share retrieved documents — and once they read each other's drafts, they share each other's mistakes.&lt;/p&gt;

&lt;p&gt;The research backs this up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Outshift (Cisco, 2026):&lt;/strong&gt; in staged five-agent debates, 75% ended in unanimous agreement on the wrong outcome. The agents folded early, skipped the hard work of alignment, and looked cheap on the token bill. (Source: VentureBeat, "AI teams agreed on the wrong answer in 75% of debates")&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A Berkeley study cited by Outshift:&lt;/strong&gt; roughly a third of the agent failures examined could be attributed to misaligned goals — agents optimising for something other than the shared objective.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outshift's production telemetry:&lt;/strong&gt; 100% of multi-agent sessions showed at least one cognitive failure, and at three cognitive errors, system efficacy dropped from 98% to 16%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conformal Social Choice (AWS, arXiv 2604.07667):&lt;/strong&gt; among cases where agents initially disagreed, 23.9% converged to unanimous &lt;em&gt;wrong&lt;/em&gt; agreement by round 3 — nearly one in four.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Three separate mechanisms drive this, and each has a name in the literature. &lt;strong&gt;Correlated mistakes:&lt;/strong&gt; as models get more capable, their errors become more similar (Goel et al., 2025), so five agents can be wrong in exactly the same way. &lt;strong&gt;Sycophancy:&lt;/strong&gt; agents tuned with human feedback tend to agree with confident answers they read (Sharma et al., 2023) — your agents flatter each other. &lt;strong&gt;Degeneration-of-Thought:&lt;/strong&gt; once a model is confident in an answer, it stops generating new ideas, even when the first answer is wrong (Liang et al., 2023).&lt;/p&gt;

&lt;p&gt;None of this shows up in your dashboard. Consensus looks like success. A low token bill looks like efficiency. The failure is silent.&lt;/p&gt;

&lt;h2&gt;
  
  
  The green tick that lies
&lt;/h2&gt;

&lt;p&gt;A CRM triage agent made the rounds on LinkedIn this week, and it's the perfect illustration. Reportedly, a hidden line in a customer email became an instruction. The agent picked the wrong customer, retried a failed API call 200 times, then closed 500 cases and sent 500 survey emails.&lt;/p&gt;

&lt;p&gt;Every run reported "success".&lt;/p&gt;

&lt;p&gt;That's the shape of production agent failure. Not a crash. Not a timeout. A confident, logged, green-ticked run that wrote wrong data back into your system as truth — so the next run trusts it even more. Errors compound. Bad data becomes training context for the next decision. By the time a human notices, the blast radius isn't one bad answer, it's hundreds of wrong records.&lt;/p&gt;

&lt;p&gt;Demos test capability. Production tests what happens when the agent is wrong and nobody is watching.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix isn't a smarter model
&lt;/h2&gt;

&lt;p&gt;Every instinct in this industry says: upgrade the model. But a smarter model makes the same failure mode &lt;em&gt;harder&lt;/em&gt; to catch, because its wrong answers sound more plausible. The fix is engineering, not intelligence. Four things, in order of impact:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Independent verification, not consensus
&lt;/h3&gt;

&lt;p&gt;Never let the agents that did the work grade the work. Verification must be independent: a separate check against ground truth — a database lookup, a schema validation, a rule the agent cannot rewrite. If your agent decides a customer is "Customer A", the verifier checks the email address against the CRM before anything is written.&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;# Verification is a separate, deterministic step — not another agent vote
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_triage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decision&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crm&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lookup_by_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decision&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;source_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;decision&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;escalate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decision&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;customer mismatch&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;decision&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;DESTRUCTIVE_ACTIONS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;require_human_approval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decision&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decision&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A verifier that can say "no" is worth more than five agents that say "yes".&lt;/p&gt;

&lt;h3&gt;
  
  
  2. An audit log of every step
&lt;/h3&gt;

&lt;p&gt;If you can't replay what the agent did, you can't debug it, and you can't prove what happened to a customer. Log the inputs, the tool calls, the intermediate decisions, and the final action — with timestamps. Outshift's new Scope tool does exactly this over OpenTelemetry traces, looking for cognitive drift from the shared goal. You don't need their tool; you need the discipline. No log, no production.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Least privilege and hard caps
&lt;/h3&gt;

&lt;p&gt;An agent should hold the minimum permissions to do its job, and nothing else. A triage agent that can &lt;em&gt;read&lt;/em&gt; cases should not be able to &lt;em&gt;close&lt;/em&gt; 500 of them in one run. Put hard caps in code, not in prompts: max retries (3, not 200), max records per run, no bulk destructive actions without a human gate. Prompts are suggestions. Code is a boundary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Caps live in code, where a prompt injection can't reach them&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;LIMITS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;maxRetries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;maxRecordsPerRun&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;bulkClose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runWithLimits&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;attempt&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;LIMITS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maxRetries&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;attempt&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;backoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;attempt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;escalate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;retry budget exhausted&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. A human approval gate at the money step
&lt;/h3&gt;

&lt;p&gt;Any action that moves money, closes a case, emails a customer, or writes to a system of record should pause for a human — at least until the automation has earned trust over hundreds of verified runs. The 95% of agent prototypes that never reach production (MIT's widely cited figure) mostly die here: they were built as demos, with no one designing the failure path.&lt;/p&gt;

&lt;h2&gt;
  
  
  A checklist before your agent touches production
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Can it be wrong silently?&lt;/strong&gt; If yes, add an independent verifier before you ship.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can one run do bulk damage?&lt;/strong&gt; Cap records per run and forbid bulk destructive actions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can a prompt injection become an instruction?&lt;/strong&gt; Treat all external text — emails, tickets, documents — as untrusted data, never as instructions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can you replay a bad run?&lt;/strong&gt; If there's no audit log, you're flying blind.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Who gets paged when it fails?&lt;/strong&gt; "Nobody, it reports success" is not an answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Would you trust it with your own account?&lt;/strong&gt; If not, don't give it your customers'.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The question to ask
&lt;/h2&gt;

&lt;p&gt;Don't ask if your agent can do the task. Every demo says yes.&lt;/p&gt;

&lt;p&gt;Ask how you'd know if it did it wrong.&lt;/p&gt;

&lt;p&gt;Agreement is not verification. A low token bill is not efficiency. And a green tick is not the truth — it's just the absence of an error message.&lt;/p&gt;

&lt;p&gt;Build the boring parts first: the verifier, the log, the caps, the human gate. Then let the agent be clever inside the boundaries you set. That's the difference between a demo that impresses a room and an automation that survives contact with real data.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I break down systems like this daily — follow for more on AI automation, web architecture, and building software that survives production.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>automation</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Your Website Doesn't Have a Design Problem. It Has a Speed Problem</title>
      <dc:creator>Irfan Gulzar</dc:creator>
      <pubDate>Thu, 05 Nov 2026 09:02:59 +0000</pubDate>
      <link>https://dev.to/irfangulzarx/your-website-doesnt-have-a-design-problem-it-has-a-speed-problem-3mhj</link>
      <guid>https://dev.to/irfangulzarx/your-website-doesnt-have-a-design-problem-it-has-a-speed-problem-3mhj</guid>
      <description>&lt;p&gt;Most founders test their website on office Wi-Fi, from a fast laptop. Their customers visit on a mid-range phone, on mobile data, halfway through a commute. That gap — between the machine you built on and the machine your customer actually uses — is where the money quietly leaks.&lt;/p&gt;

&lt;p&gt;A slow website is not a design issue. It is a sales issue. And unlike a redesign, it is measurable, fixable, and cheap to prove.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a slow page actually costs
&lt;/h2&gt;

&lt;p&gt;The numbers here are not guesses. They come from studies with real traffic behind them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deloitte and Google, "Milliseconds Make Millions" (2020)&lt;/strong&gt; — across 37 brands and roughly 30 million mobile sessions, a 0.1-second improvement in mobile site speed was linked to &lt;strong&gt;8.4% higher retail conversions&lt;/strong&gt; and &lt;strong&gt;9.2% higher average order value&lt;/strong&gt;. Travel conversions rose 10.1% for the same tenth of a second.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portent (2022)&lt;/strong&gt; — across more than 27,000 landing pages, ecommerce conversion sat at &lt;strong&gt;3.05% on pages loading in one second&lt;/strong&gt;, fell to 1.68% at two seconds, and 1.12% at three. A one-second page converted about 2.5 times better than a five-second one for ecommerce, and three times better for B2B lead generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Akamai (2017)&lt;/strong&gt; — a 100-millisecond delay in load time was associated with a &lt;strong&gt;7% drop in conversion rate&lt;/strong&gt;, measured across roughly 10 billion retail site visits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google / SOASTA (2017)&lt;/strong&gt; — as page load time rises from one second to three, the probability of a bounce increases by &lt;strong&gt;32%&lt;/strong&gt;. From one to five seconds, it jumps 90%.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read those together and the conclusion is unavoidable: nobody changed the offer, the pricing, or the copy. Only the loading time. And the loading time moved the revenue line.&lt;/p&gt;

&lt;p&gt;The honest caveat: these are large observational studies, not randomised trials. Treat the magnitudes as directional, not as a guarantee for your site. But the direction has been consistent for a decade, across every study that measured it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why your Lighthouse score can be green and your site still feels slow
&lt;/h2&gt;

&lt;p&gt;Here is the trap most teams fall into: they optimise for the lab and ignore the field.&lt;/p&gt;

&lt;p&gt;Lighthouse runs on a fast machine with a throttled connection. Your users run on real phones, real networks, real CPUs. Google knows this, which is why it judges Core Web Vitals on &lt;strong&gt;field data at the 75th percentile&lt;/strong&gt; — the experience of your slowest quarter of visitors, not your best test run.&lt;/p&gt;

&lt;p&gt;The three thresholds, current since March 2024:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LCP (Largest Contentful Paint)&lt;/strong&gt; — main content visible within &lt;strong&gt;2.5 seconds&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;INP (Interaction to Next Paint)&lt;/strong&gt; — interaction response under &lt;strong&gt;200 milliseconds&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLS (Cumulative Layout Shift)&lt;/strong&gt; — layout shift under &lt;strong&gt;0.1&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;INP is the one most teams miss. It replaced First Input Delay in 2024, and it grades your &lt;strong&gt;worst interaction&lt;/strong&gt;, not your first. A page can paint in 0.8 seconds and then lock up for two more while hydration freezes the main thread. The HTML arrived. The brain didn't.&lt;/p&gt;

&lt;p&gt;That is the most common failure mode I see in modern sites: a beautiful page that paints fast, then ignores clicks while 400KB of JavaScript hydrates a "Read more" button. Lighthouse goes green. The user leaves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measure where your customers actually are
&lt;/h2&gt;

&lt;p&gt;Stop testing on your own laptop. Start measuring the field.&lt;/p&gt;

&lt;p&gt;The simplest honest check is free: open Chrome DevTools, run a performance trace on a mid-range Android profile with 4G throttling, and watch what happens after the first paint. Better still, read your real field data in the Chrome UX Report or PageSpeed Insights — it shows the 75th-percentile numbers your actual visitors experience.&lt;/p&gt;

&lt;p&gt;If you want a number you can track in code, the &lt;code&gt;web-vitals&lt;/code&gt; library gives you the real metrics from real sessions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;onLCP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onINP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onCLS&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;web-vitals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sendToAnalytics&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// metric.name: 'LCP' | 'INP' | 'CLS'&lt;/span&gt;
  &lt;span class="c1"&gt;// metric.value: the real field value, in milliseconds (or score for CLS)&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metric&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;onLCP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sendToAnalytics&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;onINP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sendToAnalytics&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;onCLS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sendToAnalytics&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One line of instrumentation beats a hundred lab runs. It tells you what your customers feel, not what your test rig pretends.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fixes that actually move the number
&lt;/h2&gt;

&lt;p&gt;Speed work is not mysterious. The same five fixes cover most sites I audit:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Ship HTML first, hydrate only what's interactive.&lt;/strong&gt; Server-render the page. Then hydrate selectively — the checkout button, the search box — and leave the rest as plain HTML. A static hero does not need a framework runtime.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Don't hydrate the whole page. Hydrate the island that needs it.&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Suspense&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CheckoutButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./CheckoutButton&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProductPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Static HTML: ships instantly, no JS needed */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Wireless&lt;/span&gt; &lt;span class="nx"&gt;Headphones&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;hour&lt;/span&gt; &lt;span class="nx"&gt;battery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Noise&lt;/span&gt; &lt;span class="nx"&gt;cancelling&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Only this island gets JavaScript */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Suspense&lt;/span&gt; &lt;span class="nx"&gt;fallback&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CheckoutButton&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Suspense&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Kill the JavaScript you don't use.&lt;/strong&gt; Audit your bundle. Third-party scripts — chat widgets, analytics, tag managers — are usually the biggest single chunk. Every script you remove is speed you never have to optimise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Serve images like it's 2026.&lt;/strong&gt; Modern formats (AVIF/WebP), responsive sizes, &lt;code&gt;loading="lazy"&lt;/code&gt; below the fold, and explicit width/height so the layout never jumps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"hero.avif"&lt;/span&gt;
  &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"hero-480.avif 480w, hero-800.avif 800w, hero-1200.avif 1200w"&lt;/span&gt;
  &lt;span class="na"&gt;sizes=&lt;/span&gt;&lt;span class="s"&gt;"(max-width: 600px) 480px, 800px"&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"1200"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"630"&lt;/span&gt;
  &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Product hero shot"&lt;/span&gt;
  &lt;span class="na"&gt;fetchpriority=&lt;/span&gt;&lt;span class="s"&gt;"high"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Stop the layout shift.&lt;/strong&gt; Reserve space for everything that loads late — images, ads, embeds. A CLS under 0.1 is mostly a discipline problem, not a technical one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Fix your fonts and your third parties.&lt;/strong&gt; Use &lt;code&gt;font-display: swap&lt;/code&gt;, preload only the one font weight you actually render above the fold, and load every third-party script with &lt;code&gt;defer&lt;/code&gt; or after interaction. A chat widget that blocks rendering is a tax on every visitor for the benefit of the few who chat.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 30-minute speed audit
&lt;/h2&gt;

&lt;p&gt;Do this today, before you touch a redesign:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run PageSpeed Insights on your homepage, your top landing page, and your checkout — read the &lt;strong&gt;field data&lt;/strong&gt;, not the lab score.&lt;/li&gt;
&lt;li&gt;Note which Core Web Vital fails at the 75th percentile.&lt;/li&gt;
&lt;li&gt;Open DevTools, throttle to 4G, and click the main call-to-action. Time how long until it responds.&lt;/li&gt;
&lt;li&gt;List every third-party script on the page. Delete one.&lt;/li&gt;
&lt;li&gt;Check your largest image: is it AVIF/WebP, correctly sized, and lazy-loaded below the fold?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most sites find their biggest win in step 3 or 4. The fix is usually deletion, not addition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Speed is a sales metric
&lt;/h2&gt;

&lt;p&gt;A homepage that takes over three seconds on real mobile is not a design problem. It is a leak in the funnel, and it compounds: every ad click you buy lands on the same slow page, every SEO ranking you earn sends visitors into the same wait.&lt;/p&gt;

&lt;p&gt;The founders who win this are not the ones with the prettiest site. They are the ones who measured on the device their customers actually hold, fixed the worst interaction first, and treated a tenth of a second as revenue — because the data says it is.&lt;/p&gt;

&lt;p&gt;When did you last load your own website on mobile data?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I break down systems like this daily — web performance, AI automation, and the technical decisions that actually move revenue. Follow for more.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sources:&lt;/strong&gt; Deloitte &amp;amp; Google, "Milliseconds Make Millions" (2020); Portent, Site Speed and Conversion Rate research (updated 2022); Akamai, "State of Online Retail Performance" (2017); Google/SOASTA Research (2017); web.dev Core Web Vitals thresholds (2024).&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>performance</category>
      <category>javascript</category>
      <category>seo</category>
    </item>
    <item>
      <title>Why 95% of AI Agent Prototypes Never Reach Production — and How to Build One That Does</title>
      <dc:creator>Irfan Gulzar</dc:creator>
      <pubDate>Mon, 02 Nov 2026 09:04:48 +0000</pubDate>
      <link>https://dev.to/irfangulzarx/why-95-of-ai-agent-prototypes-never-reach-production-and-how-to-build-one-that-does-3mk</link>
      <guid>https://dev.to/irfangulzarx/why-95-of-ai-agent-prototypes-never-reach-production-and-how-to-build-one-that-does-3mk</guid>
      <description>&lt;p&gt;Your AI agent demo works. Your AI agent doesn't.&lt;/p&gt;

&lt;p&gt;A team builds a dazzling prototype in a week. It answers questions, books meetings, drafts replies, and everyone in the room nods. Then it meets real customers, real data, and real consequences — and it quietly dies.&lt;/p&gt;

&lt;p&gt;This is not a model problem. The model was never the hard part.&lt;/p&gt;

&lt;p&gt;MIT's 2025 report &lt;em&gt;The GenAI Divide: State of AI in Business&lt;/em&gt; found that 95% of generative AI pilots fail to deliver measurable profit-and-loss impact. Read that again: not 95% of bad ideas, but 95% of pilots — including many built by competent teams with good models. The gap between a demo and a production system is where almost every agent project is won or lost.&lt;/p&gt;

&lt;p&gt;Here is what that gap looks like, and how to survive it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The demo is not the product
&lt;/h2&gt;

&lt;p&gt;A demo runs on clean data, a friendly user, and a forgiving audience. Production runs on none of those.&lt;/p&gt;

&lt;p&gt;In a demo, the input is the one happy-path example you rehearsed. In production, it is a form field full of typos, a CRM record missing half its fields, and an API that fails at 2 a.m. A wrong answer in a demo is a laugh; in production it is a refund issued twice or an email sent to the wrong client. Demos do not need error handling. Production is mostly error handling.&lt;/p&gt;

&lt;p&gt;That is the first uncomfortable truth: the model is perhaps 10% of a working automation. The rest is the boring engineering nobody posts about — observability, retry logic, guardrails, a data layer that does not lie, and a human who can hit stop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why prototypes die: five production gaps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. No permission boundaries
&lt;/h3&gt;

&lt;p&gt;A demo agent usually runs with your credentials, or with a single admin token, because that is the fastest way to make it work. In production, that is a liability with an API key.&lt;/p&gt;

&lt;p&gt;Every tool an agent can call is a door. A production agent needs scoped, least-privilege credentials per task, and an explicit list of actions it is never allowed to take without a human. Before you ship, answer this precisely: if this agent went rogue for ten minutes, what is the worst thing it could do?&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Messy data, not model quality
&lt;/h3&gt;

&lt;p&gt;Demos run on curated examples. Production data is duplicated, stale, half-empty, and contradictory. The same customer exists three times in the CRM under three spellings of their name. The price list has two versions. The calendar has a cancelled meeting that was never deleted.&lt;/p&gt;

&lt;p&gt;An agent that trusts its data blindly will confidently act on lies. A production system validates before it acts. This is why so many agent projects stall at integration, not intelligence. The model was fine. The data layer was not.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. No observability
&lt;/h3&gt;

&lt;p&gt;When a workflow breaks, you can point at the exact step that failed. When an agent breaks, you often get a confident answer and no explanation of how it got there. Production agents need logs for everything — goal, tools called, arguments, outputs, and final action — so a run can be replayed step by step. When a customer asks why something happened, "the agent decided" is not an answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Cost and drift nobody budgeted for
&lt;/h3&gt;

&lt;p&gt;A workflow costs roughly the same every time it runs. An agent does not. Token usage varies with every run, tool calls multiply, and a retry loop can turn a cheap task into an expensive one. Behaviour also drifts: the same prompt that worked in October can behave differently after a model update in November.&lt;/p&gt;

&lt;p&gt;Production means budgets per run, capped retries, and regression tests run on a schedule against the live system. If you would not ship a normal feature without tests, do not ship an agent without them either.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. No human at the money step
&lt;/h3&gt;

&lt;p&gt;The most dangerous agent is one that can move money, message customers, or change records with no human in the loop — not because agents are malicious, but because they are confident. The rule I use with clients is simple: AI can prepare, draft, and recommend, but a human approves anything irreversible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture that survives: deterministic backbone, AI at the edges
&lt;/h2&gt;

&lt;p&gt;The agents that reach production almost all look the same, and they do not look like the demos. They have a deterministic backbone — a workflow with defined steps, validations, and fallbacks — and they use AI only where judgement is actually needed.&lt;/p&gt;

&lt;p&gt;Take a lead-handling automation. Four of its five steps are deterministic: take the form lead, enrich it, check it against rules, and create the deal in the CRM. Only one step needs judgement: scoring the lead. That is a workflow with one language-model call in the middle — not an agent problem.&lt;/p&gt;

&lt;p&gt;Here is the shape of that pattern in code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_lead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lead&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Deterministic steps: same input, same output, every time
&lt;/span&gt;    &lt;span class="n"&gt;lead&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lead&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="c1"&gt;# reject bad data early, loudly
&lt;/span&gt;    &lt;span class="n"&gt;lead&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;enrich&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lead&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="c1"&gt;# one known source, not a web search
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;passes_rules&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lead&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;     &lt;span class="c1"&gt;# business rules, not model vibes
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;queue_for_review&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lead&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;failed rules&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# AI only where judgement is needed
&lt;/span&gt;    &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;score_lead_with_llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lead&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Human at the money step: nothing irreversible happens unseen
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;request_approval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lead&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;create deal + notify sales&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="nf"&gt;queue_for_review&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lead&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low score&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;And the guardrails around it are explicit, not implied:&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;"agent_policy"&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;"allowed_tools"&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;"crm.read"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"crm.create_deal"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"forbidden_tools"&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;"email.send"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"payment.refund"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"max_retries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"max_cost_per_run_usd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"requires_human_approval"&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;"create_deal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"send_to_customer"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"log_everything"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;Notice what this buys you. When it breaks, you know which step broke. When it is wrong, a human saw it before the customer did. That is not less ambitious than a fully autonomous agent. It is the version that still exists in six months.&lt;/p&gt;

&lt;h2&gt;
  
  
  A production checklist before you launch
&lt;/h2&gt;

&lt;p&gt;Run through this before any agent touches real customers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Permissions:&lt;/strong&gt; scoped credentials, an explicit forbidden-action list, and a tested answer to "what is the worst ten minutes of rogue behaviour?"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validation:&lt;/strong&gt; every input checked, every tool output sanity-checked before the next step runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability:&lt;/strong&gt; full run logs you can replay, plus alerts when a run fails, loops, or exceeds its cost budget.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retries and fallbacks:&lt;/strong&gt; capped retries with backoff, and a graceful fallback — queue for a human — instead of retrying forever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human approval:&lt;/strong&gt; a person approves anything irreversible, especially anything involving money or customer-facing messages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regression tests:&lt;/strong&gt; your ten most important tasks, run on a schedule against the live system, with failures alerting a human.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you cannot tick all six, you do not have a production agent yet. You have a demo with a launch date. Fix the checklist first — it is cheaper than explaining a failure to a customer later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop asking which model to use
&lt;/h2&gt;

&lt;p&gt;The model question is the easiest question in agent building, and the least important. Swap the model in a well-built system and the system still works. Start instead with the question that decides whether your agent survives contact with reality: what happens when it fails? Build the boring backbone first. Earn the agent later.&lt;/p&gt;




&lt;p&gt;I break down systems like this daily — follow for more.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>automation</category>
      <category>agents</category>
    </item>
    <item>
      <title>Your Title Doesn't Ship. Your Live Link Does.</title>
      <dc:creator>Irfan Gulzar</dc:creator>
      <pubDate>Thu, 29 Oct 2026 09:21:56 +0000</pubDate>
      <link>https://dev.to/irfangulzarx/your-title-doesnt-ship-your-live-link-does-8ij</link>
      <guid>https://dev.to/irfangulzarx/your-title-doesnt-ship-your-live-link-does-8ij</guid>
      <description>&lt;p&gt;LinkedIn is full of titles. Titles don't ship.&lt;/p&gt;

&lt;p&gt;"Software Engineer | Full Stack | AI Enthusiast | Open to Work" — I have seen the same badge-line on a dozen profiles this week. None of them tell me whether you can build something a stranger can click.&lt;/p&gt;

&lt;p&gt;That is not a criticism of ambition. It is a description of how hiring actually works in 2026. Recruiters cross-reference now. They check GitHub, they check a personal site, they click a live link. A title is a claim. A deployed app is evidence.&lt;/p&gt;

&lt;p&gt;If you are a developer looking for work, clients, or your next role, this is the one shift that matters most: stop polishing the headline first. Ship one small thing, put the link where people can find it, and let the work introduce you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The recruiter check changed
&lt;/h2&gt;

&lt;p&gt;A few years ago, a profile was the proof. Your headline, your summary, your list of skills — that was the package a recruiter judged.&lt;/p&gt;

&lt;p&gt;That package broke for two reasons. First, everyone learned the same keywords, so the keywords stopped meaning anything. Second, AI tools made it trivial to produce a polished-looking profile without producing anything real. A summary can be generated in ten seconds. A working product cannot.&lt;/p&gt;

&lt;p&gt;So the check moved one step further out. Can I click something you built? Does it load? Does it do one thing clearly? Does the code behind it look like it was written by someone who understands the problem?&lt;/p&gt;

&lt;p&gt;One live link answers all of that faster than a paragraph of adjectives ever will. It shows taste, follow-through, and judgement — the three things no headline can prove.&lt;/p&gt;

&lt;h2&gt;
  
  
  A title says what you want to be called
&lt;/h2&gt;

&lt;p&gt;There is nothing wrong with calling yourself a full-stack developer. The problem is only that the title carries no information about range, depth, or reliability.&lt;/p&gt;

&lt;p&gt;Two developers can hold the same title and be completely different hires. One has shipped a booking form that handles real validation, real errors, and real edge cases. The other has followed tutorials and never deployed anything. On paper they look identical. In a browser tab they do not.&lt;/p&gt;

&lt;p&gt;That is why "proof converts, claims don't" is not a slogan. It is how trust works. A claim asks the reader to believe you. Proof lets the reader verify you, without needing to take your word for anything.&lt;/p&gt;

&lt;p&gt;If you want to be taken seriously, give people something to verify.&lt;/p&gt;

&lt;h2&gt;
  
  
  What counts as proof
&lt;/h2&gt;

&lt;p&gt;Proof does not mean a huge project. In fact, huge projects are often worse proof, because nobody has time to explore them and they are rarely finished.&lt;/p&gt;

&lt;p&gt;Good proof is small, finished, and legible. It has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One clear job.&lt;/strong&gt; A visitor understands in five seconds what it does.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A live URL.&lt;/strong&gt; Not a screenshot, not a repo link alone — something that loads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readable code.&lt;/strong&gt; A repo a reviewer can open and follow without a guided tour.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A real decision in it.&lt;/strong&gt; Something you chose, and can explain why.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples that work: a single-page tool that solves one annoying problem, a landing page with a working form and proper validation, a small dashboard that fetches real data and handles loading and error states honestly. The scope is small. The finish is what sells it.&lt;/p&gt;

&lt;p&gt;Here is the test I use: if a stranger clicks your link on their phone, on mobile data, and cannot tell what you built within ten seconds, it is not proof yet. Simplify it until they can.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ship one thing this weekend
&lt;/h2&gt;

&lt;p&gt;You do not need a new stack, a new course, or permission. Pick the smallest useful thing you can finish, and finish it properly.&lt;/p&gt;

&lt;p&gt;A practical shape for a weekend proof project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pick one user and one task — for example, a local clinic that needs a booking enquiry form, or a freelancer who needs a one-page price calculator.&lt;/li&gt;
&lt;li&gt;Build it as a single page with real validation, not placeholder alerts.&lt;/li&gt;
&lt;li&gt;Deploy it so it has a real URL.&lt;/li&gt;
&lt;li&gt;Write a short README: what it does, who it is for, and what you would improve next.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The deployment step is the part most people skip, and it is the part that turns a project into proof. A minimal example with a static page is enough to start:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# From your project folder, ship it&lt;/span&gt;
npx vercel &lt;span class="nt"&gt;--prod&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the form itself should behave like a real product, not a demo. Validate on the client, show errors next to the field, and never leave the user guessing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validateBooking&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;form&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="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please add a name.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;\S&lt;/span&gt;&lt;span class="sr"&gt;+@&lt;/span&gt;&lt;span class="se"&gt;\S&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;\.\S&lt;/span&gt;&lt;span class="sr"&gt;+$/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;That email does not look right.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pick a date for the booking.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// If errors is empty, submit. Otherwise, render each&lt;/span&gt;
&lt;span class="c1"&gt;// message next to its field — no silent failures.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is not impressive code, and that is the point. Reviewers are not looking for cleverness. They are looking for care: handled states, honest errors, and a page that works when something goes wrong.&lt;/p&gt;

&lt;p&gt;Then put the link in your featured section, in your GitHub profile README, and at the top of your personal site. Do not bury your best evidence three clicks deep.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let the work introduce you
&lt;/h2&gt;

&lt;p&gt;I won my first real clients because they could click something I built — not because my headline was clever. They did not hire a title. They hired the evidence that I could take a vague idea and turn it into something that loads, works, and looks considered.&lt;/p&gt;

&lt;p&gt;That is still how it works, only more so. In a market full of generated profiles and generated portfolios, the scarcest signal is a finished thing with your name on it.&lt;/p&gt;

&lt;p&gt;So before you polish your headline this week, ask a simpler question: what is the one live link on your profile that you are genuinely proud of?&lt;/p&gt;

&lt;p&gt;If you do not have one yet, that is your weekend job. Not a rebrand. Not a new headline. One small, finished, deployed thing — and a link a stranger can click.&lt;/p&gt;

&lt;p&gt;I break down systems like this daily — follow for more.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>SEO vs GEO Is the Wrong Argument: AI Search Sends Less Traffic and Better Buyers</title>
      <dc:creator>Irfan Gulzar</dc:creator>
      <pubDate>Mon, 26 Oct 2026 09:07:28 +0000</pubDate>
      <link>https://dev.to/irfangulzarx/seo-vs-geo-is-the-wrong-argument-ai-search-sends-less-traffic-and-better-buyers-4kb4</link>
      <guid>https://dev.to/irfangulzarx/seo-vs-geo-is-the-wrong-argument-ai-search-sends-less-traffic-and-better-buyers-4kb4</guid>
      <description>&lt;p&gt;Everyone is arguing SEO versus GEO, as if one of them has to win. The numbers coming out of real analytics accounts suggest the argument itself is broken — because it is measuring the wrong thing.&lt;/p&gt;

&lt;p&gt;Traffic was always a proxy. It stood in for attention, then for interest, then — hopefully — for revenue. AI search has broken that chain in an interesting way: it sends fewer visitors, but the visitors it does send are much closer to buying. If your dashboard only counts sessions, AI search looks like a disaster. If it counts signups, it looks like the best channel you have.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers that break the old dashboard
&lt;/h2&gt;

&lt;p&gt;Ahrefs shared their own data: AI search accounted for just 0.5% of their traffic, but 12.1% of their signups. That is not a rounding error. It is a completely different ratio from organic search, where a large volume of visits produces a small share of conversions.&lt;/p&gt;

&lt;p&gt;An Opollo study across 312 IT firms points the same way: AI referrals converted at 14.2%, against 2.8% for Google organic. Again, the story is not volume. It is intent. By the time an AI answer sends someone to your site, that person has usually already had the comparison, the objection handling, and the shortlisting done for them — inside the answer.&lt;/p&gt;

&lt;p&gt;And Ethan Smith's analysis adds the part most teams miss: roughly 45 billion monthly AI sessions, with about 83% happening inside apps — ChatGPT, Gemini, Perplexity, Claude — rather than on the open web. Most AI activity is not happening on websites at all. Your site is not the destination any more. It is the source the answer was built from, and occasionally the place the buyer lands to finish the job.&lt;/p&gt;

&lt;p&gt;Put those three data points together and the picture changes. The funnel did not disappear. It moved upstream, into the answer itself. The click is no longer the start of the buying journey. It is near the end of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why an AI referral converts differently
&lt;/h2&gt;

&lt;p&gt;A Google click is often the start of research. Someone types a broad query, opens five tabs, and bounces from four of them. An AI referral is different because the filtering already happened before the visit.&lt;/p&gt;

&lt;p&gt;The AI has already:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understood the question in full sentences, not keywords&lt;/li&gt;
&lt;li&gt;Compared options against the buyer's actual criteria&lt;/li&gt;
&lt;li&gt;Answered the obvious objections in the answer itself&lt;/li&gt;
&lt;li&gt;Recommended a shortlist, with reasons&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the visitor who arrives is pre-qualified in a way a search click rarely is. They are not asking "what is this?" They are asking "is this the one, and how do I start?" That is why a tiny share of traffic can produce an outsized share of signups. The denominator shrank. The numerator did not shrink nearly as much.&lt;/p&gt;

&lt;p&gt;This also explains why the usual SEO panic is misplaced. Yes, AI answers will eat some informational traffic — the "what is X" visits that never converted anyway. Losing those visits hurts a traffic chart. It does not necessarily hurt revenue. The visits worth keeping are the ones attached to a buying question, and those are exactly the visits AI answers are now routing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop optimising for clicks. Start optimising for the answer.
&lt;/h2&gt;

&lt;p&gt;If the click is now the end of the journey, the work moves earlier: into being the source the answer quotes, and into being the obvious next step once it does.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Say what you do in one quotable paragraph
&lt;/h3&gt;

&lt;p&gt;AI answers quote pages that state a claim plainly, with evidence on the same page. A homepage that says "we help businesses grow with innovative solutions" gives an answer engine nothing to quote — because it says nothing specific. A page that says who you serve, what problem you solve, and how you are different, in the first paragraph, gives it a sentence it can lift whole.&lt;/p&gt;

&lt;p&gt;Write the paragraph you would want quoted. Then check whether it actually appears on the page, in crawlable HTML, not buried in a JavaScript widget.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Answer the buyer's real question, not the keyword
&lt;/h3&gt;

&lt;p&gt;Ranking content targets a keyword. Answer content targets a question a buyer actually asks, in the words they ask it: "which tool is best for a small team on a budget?", "what does it cost after the first year?", "what breaks when you scale past 10,000 users?" Pages built around those questions — with a direct answer first and the detail after — are the pages AI systems reach for.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Make the conversion step obvious from the answer
&lt;/h3&gt;

&lt;p&gt;If an AI answer sends a buyer to your pricing page, that page has to finish the job: clear pricing, a visible next step, and proof — testimonials, case results, a comparison — on the same page. A buyer who arrives pre-sold and then has to hunt for a signup button is a buyer you will lose to a competitor whose page does not make them hunt.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Measure signups per AI referral, not AI sessions
&lt;/h3&gt;

&lt;p&gt;This is the dashboard change that matters most. Split your analytics so AI referrals are a separate source, and track them all the way to signup, not just to session. A simple way to start is to segment referral traffic from the major AI platforms and compare its signup rate against organic search over the same period:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Segment AI referrals in your analytics by referrer&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;aiReferrers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chatgpt.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;perplexity.ai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;claude.ai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gemini.google.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isAiReferral&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aiReferrers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;referrer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Tag the session, then compare signup rate: AI referrals vs organic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point is not the code. It is the comparison. Once you can see that one AI referral is worth several organic visits, the internal argument about "losing traffic" ends, because the team is finally looking at the number that pays.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ranking still matters — but the finish line moved
&lt;/h2&gt;

&lt;p&gt;None of this means SEO is dead. Ranking still matters, for two reasons. First, the pages AI systems trust are usually the pages that already earned authority the old-fashioned way: consistent content, real expertise, third-party mentions. Second, not every buyer journey runs through an AI answer yet. Search still drives discovery for a huge share of queries.&lt;/p&gt;

&lt;p&gt;What changed is the finish line. It used to be the most traffic. Now it is the most-quoted answer on the question buyers actually ask — followed by a page that converts the buyer who arrives. Traffic without that second half is just a chart going up. A cited answer with a working signup path is a business.&lt;/p&gt;

&lt;p&gt;So stop asking whether SEO or GEO wins. Ask a better question: when an AI answer mentions your category, does it mention you — and when it sends you a buyer, does your page close?&lt;/p&gt;

&lt;p&gt;That is the game now. The dashboards just have not caught up yet.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I break down systems like this daily — follow for more on web architecture, AI automation, and getting cited by the machines that now decide what gets read.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>seo</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Your Vibe-Coded Site Works. AI Search Can't See It.</title>
      <dc:creator>Irfan Gulzar</dc:creator>
      <pubDate>Thu, 22 Oct 2026 09:50:53 +0000</pubDate>
      <link>https://dev.to/irfangulzarx/your-vibe-coded-site-works-ai-search-cant-see-it-2ep5</link>
      <guid>https://dev.to/irfangulzarx/your-vibe-coded-site-works-ai-search-cant-see-it-2ep5</guid>
      <description>&lt;p&gt;Last weekend someone shipped a full landing page — pricing section, testimonials, a working contact form — without writing a single line of code. It looked flawless in the browser. Animations, gradients, the lot.&lt;/p&gt;

&lt;p&gt;Then they asked ChatGPT what the site was about.&lt;/p&gt;

&lt;p&gt;It had no idea the site existed. Not a wrong answer — &lt;em&gt;no&lt;/em&gt; answer at all.&lt;/p&gt;

&lt;p&gt;That's the quiet failure mode of the vibe-coding boom. These tools didn't just change &lt;em&gt;who&lt;/em&gt; builds websites. They quietly changed &lt;em&gt;what&lt;/em&gt; gets indexed. And most vibe-built sites ship on the one rendering model that makes them invisible to AI search.&lt;/p&gt;

&lt;h2&gt;
  
  
  The vibe stack defaults to client-side rendering
&lt;/h2&gt;

&lt;p&gt;Most AI builders — Lovable, v0, Bolt, Replit's agent mode — scaffold React/Vite-style single-page apps. Your entire page is assembled &lt;em&gt;in the browser at runtime&lt;/em&gt;. The HTML the server actually sends looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Loading...&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/src/main.tsx"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the entire page. A few hundred bytes of "we'll get back to you." In your browser, JavaScript fills it in within milliseconds. To a crawler, it is a blank wall with a polite title.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why bots don't see what you see
&lt;/h2&gt;

&lt;p&gt;Fetching HTML is cheap. Executing JavaScript is expensive — a full browser context, memory, timeouts, multiplied across billions of pages. Crawlers operate on budgets, and those budgets are spent on the highest-value work first.&lt;/p&gt;

&lt;p&gt;Google invests in a rendering pipeline for its index, and even &lt;em&gt;that&lt;/em&gt; is queued and delayed — JS-rendered content routinely enters the index days behind the HTML version. AI crawlers — GPTBot, ClaudeBot, the bots that decide whether ChatGPT or Claude ever cite your site — run leaner still. The widely observed behaviour: they fetch the raw HTML and move on. No JavaScript execution, no hydration, no content.&lt;/p&gt;

&lt;p&gt;So the question that matters is no longer "does my site look good?" It is: &lt;strong&gt;what does my site look like with JavaScript switched off?&lt;/strong&gt; If the answer is an empty &lt;code&gt;div&lt;/code&gt;, then as far as AI search is concerned, your content does not exist. There is nothing to cite, quote, or recommend — no matter how beautiful it renders in Chrome.&lt;/p&gt;

&lt;p&gt;This is exactly why the new SEO conversation has shifted from rankings to citations. An AI answer engine doesn't browse your site like a visitor. It reads what its crawler could read, and it quotes what it could understand. An empty HTML shell gives it nothing to work with.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 60-second test
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;curl&lt;/code&gt; is the most honest reviewer your site will ever meet. It shows you exactly what a no-JS bot sees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://your-site.com | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://your-site.com | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 600
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the byte count is in the low hundreds and the output is a shell with an empty root &lt;code&gt;div&lt;/code&gt;, your page is invisible to AI search. Try it right now — the result takes five seconds and has ended more than a few launch-day celebrations.&lt;/p&gt;

&lt;p&gt;For comparison, run the same test on a server-rendered page and watch kilobytes of real headings, paragraphs, and links stream past. That is the difference between being quotable and being a loading spinner.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix — you don't have to give up the vibe
&lt;/h2&gt;

&lt;p&gt;Vibe-coding the &lt;em&gt;content&lt;/em&gt; is fine. Shipping the &lt;em&gt;rendering&lt;/em&gt; client-side is the problem. The fixes are all on the delivery layer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Server-render or statically generate.&lt;/strong&gt; Frameworks that ship HTML on first byte — Next.js (App Router), Astro, Nuxt, SvelteKit with prerendering — give every bot the full page immediately. The browser still hydrates into the interactive app your users see; the crawler never needed the interactivity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Prerender as a bridge.&lt;/strong&gt; If you're locked into a client-side build, prerendering services generate static HTML snapshots of your routes and serve them to crawlers. It is not as clean as true SSR, but it converts an invisible page into a readable one in an afternoon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Prioritise the pages AI needs to quote.&lt;/strong&gt; Your homepage, pricing, and services pages are the ones answer engines will cite. A blog post buried three clicks deep matters less than the page that says, in plain words, what you do. Make sure &lt;em&gt;those&lt;/em&gt; pages render as HTML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Don't rely on "Google renders JavaScript" as your safety net.&lt;/strong&gt; Even Google's rendering is budgeted and delayed — and AI crawlers are stricter still. "It'll probably get rendered eventually" is not a strategy; it is a hope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ship HTML, not apps
&lt;/h2&gt;

&lt;p&gt;The irony is sharp: the tools that made building websites effortless quietly rebuilt the exact problem the industry spent a decade solving. We fought the client-side-rendering wars in the 2010s, learned that HTML-first wins for discoverability, and then vibe-coding reintroduced the SPA as the default — this time to people who never saw the first war.&lt;/p&gt;

&lt;p&gt;So here's the practical checklist before your next launch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Build with the vibe tools for speed, render like it's 2009 for the bots:&lt;/strong&gt; HTML first, JavaScript as enhancement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;curl&lt;/code&gt; every launch.&lt;/strong&gt; If a page serves under a couple of kilobytes of real text content, fix the rendering before you announce it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Say the plain truth in text.&lt;/strong&gt; A single clear paragraph describing what you do beats a clever animation that no bot will ever watch. AI search rewards clarity, not cleverness.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your site can be both stunning &lt;em&gt;and&lt;/em&gt; visible. It just has to arrive as a page, not a promise.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I break down systems like this daily — follow for more on web architecture, AI automation, and getting cited by the machines that now decide what gets read.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>seo</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
