<?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: Ray</title>
    <description>The latest articles on DEV Community by Ray (@isray_notarray).</description>
    <link>https://dev.to/isray_notarray</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%2F1125411%2Fd2fcd426-1e95-4df9-8a04-f82df08e90d3.jpeg</url>
      <title>DEV Community: Ray</title>
      <link>https://dev.to/isray_notarray</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/isray_notarray"/>
    <language>en</language>
    <item>
      <title>design.md: If Your AI-Generated UI Keeps Drifting, You're Missing Google's design.md</title>
      <dc:creator>Ray</dc:creator>
      <pubDate>Sat, 27 Jun 2026 06:41:39 +0000</pubDate>
      <link>https://dev.to/isray_notarray/designmd-if-your-ai-generated-ui-keeps-drifting-youre-missing-googles-designmd-4abh</link>
      <guid>https://dev.to/isray_notarray/designmd-if-your-ai-generated-ui-keeps-drifting-youre-missing-googles-designmd-4abh</guid>
      <description>&lt;p&gt;Have you ever done some Vibe Coding and noticed the AI's layout is always a little off? You keep saying "the spacing is wrong here, the colour is inconsistent there", and it still produces a slightly broken screen? If yes, the real reason is that you haven't given the AI the rules of your design system properly.&lt;/p&gt;

&lt;p&gt;To fix exactly that, this post walks through &lt;strong&gt;design.md&lt;/strong&gt;, an AI design system spec released by Google Labs. The goal is to let AI Coding tools like Claude Code, Cursor, and GitHub Copilot actually read your design system and produce consistent UI — so you don't have to keep repeating "wrong colour, wrong font size" forever.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're not familiar yet with rules files for AI like CLAUDE.md / AGENTS.md, take a look at &lt;a href="https://israynotarray.com/en/ai/2026/03/10/claude-md-rules-for-ai-writing-tips/" rel="noopener noreferrer"&gt;CLAUDE.md and Rules for AI: Writing Tips That Make AI Understand Your Project&lt;/a&gt; and &lt;a href="https://israynotarray.com/en/ai/2026/01/20/agent-skills-vs-mcp-token-efficient/" rel="noopener noreferrer"&gt;Agent Skills: More Token-Efficient Than MCP&lt;/a&gt; first — it'll make a lot more sense why design.md exists.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where design.md came from
&lt;/h2&gt;

&lt;p&gt;design.md actually comes out of Stitch, Google's AI design tool (first shown at Google I/O 2025). Stitch is a UI design tool powered by Gemini — you give it a Prompt or upload a sketch and it generates a UI screen, frontend code included.&lt;/p&gt;

&lt;p&gt;Around 2026, Google released the design.md format itself under Apache 2.0 on GitHub (&lt;a href="https://github.com/google-labs-code/design.md" rel="noopener noreferrer"&gt;google-labs-code/design.md&lt;/a&gt;). What does that mean in practice? They're trying to "standardise" Stitch's design system rules.&lt;/p&gt;

&lt;p&gt;The most common pain point for Vibe Coding developers is inconsistent UI and inconsistent style. But if you open-source this design spec, the business value gets pretty huge — whether you use Claude Code, Cursor, GitHub Copilot, or any other AI Coding tool, you can use this spec to produce consistent UI.&lt;/p&gt;

&lt;p&gt;A few examples of what that gets Google:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Becoming the standard means owning the definition.&lt;/strong&gt; Think OpenAPI or Kubernetes — looked harmless at launch, but once everyone adopted them, the contributor with the loudest voice on where the spec goes was the one who shipped it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Other AI tools voluntarily become allies.&lt;/strong&gt; Once Claude Code, Cursor, and Copilot start marketing "we support design.md", competitors are basically promoting Google's format for free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The training data flywheel.&lt;/strong&gt; People will put their project's design.md in public repos. Structured design tokens plus human-written rationale is honestly the perfect combo for AI training data. Future Gemini gets stronger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stitch's free marketing funnel.&lt;/strong&gt; Once developers get used to design.md, when they need a "tool that speaks design.md", the first thing they think of is Stitch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Big-company open source that looks like a loss is usually trading time for ecosystem. Chromium, Kubernetes, TensorFlow all played this game — on the surface it's a community contribution, in reality it's using "free" to lock in the standard early.&lt;/p&gt;

&lt;h2&gt;
  
  
  What problem is design.md actually solving?
&lt;/h2&gt;

&lt;p&gt;Basically just this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Making sure the UI that AI generates uses the same colours, font sizes, and corner radii every time.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Everyone Vibe Coding has hit this. You ask the AI to make a Button, and then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first time it gives you &lt;code&gt;#3B82F6&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The second time &lt;code&gt;#2563EB&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The third time straight up &lt;code&gt;bg-blue-500&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The screen looks fine, all blue. But they're not actually the same blue, so your project ends up with a whole watercolour palette of "blues". Font sizes have the same issue — sometimes &lt;code&gt;1.25rem&lt;/code&gt;, sometimes &lt;code&gt;20px&lt;/code&gt;, sometimes &lt;code&gt;text-xl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This kind of inconsistency makes the UI feel disjointed, which makes the user experience inconsistent, which hurts the brand.&lt;/p&gt;

&lt;p&gt;Why does this happen? The main reason is you haven't given the AI a "design system rules" document.&lt;/p&gt;

&lt;p&gt;"Can't I just put it in CLAUDE.md?" — you can. But CLAUDE.md (and AGENTS.md) are "natural-language rules" for the AI. There's no structured palette or token system. After reading it, the AI still has to guess "which hex is Primary" or "which corner radius should this button use", and it ends up guessing anyway.&lt;/p&gt;

&lt;p&gt;So design.md is basically turning that "design system rules" document into a file that &lt;strong&gt;machines can parse precisely + humans can understand the reasoning behind&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does design.md actually look like?
&lt;/h2&gt;

&lt;p&gt;Pretty simple — design.md is just a Markdown file. The structure splits into two parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;YAML Front Matter&lt;/strong&gt;: the precise design tokens (colours, typography, spacing, corner radius, components).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Markdown body&lt;/strong&gt;: the design rationale — why this colour, when to use it, when not to use it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By splitting the file this way, the AI doesn't just know "Primary is &lt;code&gt;#1A1C1E&lt;/code&gt;" — it also knows "Primary is the deep ink used for headlines and core text". So when it produces UI, it's a lot less likely to use the wrong colour for a button or the wrong size for a piece of text.&lt;/p&gt;

&lt;h3&gt;
  
  
  YAML token block
&lt;/h3&gt;

&lt;p&gt;The YAML block looks roughly like this:&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="nn"&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;Heritage&lt;/span&gt;
&lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;primary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#1A1C1E"&lt;/span&gt;
  &lt;span class="na"&gt;secondary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#6C7278"&lt;/span&gt;
  &lt;span class="na"&gt;tertiary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#B8422E"&lt;/span&gt;
  &lt;span class="na"&gt;neutral&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;#F7F5F2"&lt;/span&gt;
&lt;span class="na"&gt;typography&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;h1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Public Sans&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3rem&lt;/span&gt;
  &lt;span class="na"&gt;body-md&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Public Sans&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1rem&lt;/span&gt;
&lt;span class="na"&gt;rounded&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;4px&lt;/span&gt;
  &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;8px&lt;/span&gt;
&lt;span class="na"&gt;spacing&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;8px&lt;/span&gt;
  &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;16px&lt;/span&gt;
&lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;button-primary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{colors.tertiary}"&lt;/span&gt;
    &lt;span class="na"&gt;textColor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{colors.on-tertiary}"&lt;/span&gt;
    &lt;span class="na"&gt;rounded&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{rounded.sm}"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few key points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;colors&lt;/code&gt;, &lt;code&gt;typography&lt;/code&gt;, &lt;code&gt;rounded&lt;/code&gt;, &lt;code&gt;spacing&lt;/code&gt;, &lt;code&gt;components&lt;/code&gt; are the five main token categories.&lt;/li&gt;
&lt;li&gt;Tokens can reference each other — &lt;code&gt;button-primary&lt;/code&gt;'s &lt;code&gt;backgroundColor&lt;/code&gt; is &lt;code&gt;"{colors.tertiary}"&lt;/code&gt;, so when you change &lt;code&gt;tertiary&lt;/code&gt; later, everything using it updates automatically.&lt;/li&gt;
&lt;li&gt;Colours support any valid CSS colour string: hex, rgb, hsl, oklch — all good.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've used Tailwind's &lt;code&gt;tailwind.config.js&lt;/code&gt; or the W3C Design Tokens Format Module (DTCG), this'll feel familiar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Markdown body block
&lt;/h3&gt;

&lt;p&gt;After the closing &lt;code&gt;---&lt;/code&gt; of the YAML, you get the design reasoning written for humans (and AI) to read.&lt;/p&gt;

&lt;p&gt;Officially recommended section order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overview&lt;/li&gt;
&lt;li&gt;Colors&lt;/li&gt;
&lt;li&gt;Typography&lt;/li&gt;
&lt;li&gt;Layout&lt;/li&gt;
&lt;li&gt;Elevation &amp;amp; Depth&lt;/li&gt;
&lt;li&gt;Shapes&lt;/li&gt;
&lt;li&gt;Components&lt;/li&gt;
&lt;li&gt;Do's and Don'ts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only &lt;code&gt;Colors&lt;/code&gt; (and the primary colour inside it) is &lt;strong&gt;required&lt;/strong&gt;. The rest is optional — write them only if your design system has that piece.&lt;/p&gt;

&lt;p&gt;A concrete example — the Colors block might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Colors&lt;/span&gt;

Primary (#1A1C1E): Deep ink for headlines and core text.
Use on light surfaces to maximize legibility.

Tertiary (#B8422E): Warm rust accent reserved for primary actions
and brand moments. Avoid using as body text colour due to contrast.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's basically telling the AI "this colour is called Tertiary, use it for primary action buttons, don't use it for body text".&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait — there's a CLI?
&lt;/h2&gt;

&lt;p&gt;Yep. design.md ships with a CLI that does four things: &lt;code&gt;lint&lt;/code&gt;, &lt;code&gt;diff&lt;/code&gt;, &lt;code&gt;export&lt;/code&gt;, &lt;code&gt;spec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Install and use:&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; @google/design.md
npx @google/design.md lint DESIGN.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Windows the &lt;code&gt;.md&lt;/code&gt; extension can get eaten by file association, so use the &lt;code&gt;designmd&lt;/code&gt; alias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-p&lt;/span&gt; @google/design.md designmd lint DESIGN.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  lint: validate the DESIGN.md structure
&lt;/h3&gt;

&lt;p&gt;Same vibe as ESLint, Stylelint, Prettier. &lt;code&gt;lint&lt;/code&gt; checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether the YAML schema is correct&lt;/li&gt;
&lt;li&gt;Whether token references are broken (e.g. &lt;code&gt;{colors.tertiery}&lt;/code&gt;, missing an a?!)&lt;/li&gt;
&lt;li&gt;Whether there's a primary colour&lt;/li&gt;
&lt;li&gt;Whether WCAG AA contrast passes (this one's the killer feature)&lt;/li&gt;
&lt;li&gt;Whether there are orphan tokens defined but never used&lt;/li&gt;
&lt;li&gt;Whether the section order matches the recommendation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the WCAG AA rule, it tells you straight up "&lt;code&gt;on-secondary&lt;/code&gt; against &lt;code&gt;secondary&lt;/code&gt; only hits X.X:1 contrast, doesn't pass AA". Accessibility checks baked right into the design system file.&lt;/p&gt;

&lt;h3&gt;
  
  
  diff: compare two versions
&lt;/h3&gt;

&lt;p&gt;Like &lt;code&gt;git diff&lt;/code&gt; for design systems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @google/design.md diff old/DESIGN.md new/DESIGN.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tells you which tokens changed, which were deleted, which were added. Use case: bump &lt;code&gt;primary&lt;/code&gt; from &lt;code&gt;#1A1C1E&lt;/code&gt; to &lt;code&gt;#0A0A0A&lt;/code&gt; and want to know "how many components are about to change colour because of this".&lt;/p&gt;

&lt;h3&gt;
  
  
  export: convert to other formats
&lt;/h3&gt;

&lt;p&gt;This one's genuinely impressive, especially if you want design.md as the "upstream" source.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;json-tailwind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Converts to a Tailwind v3 config object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;css-tailwind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Converts to a Tailwind v4 &lt;code&gt;@theme&lt;/code&gt; CSS block&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dtcg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Converts to the W3C Design Tokens Format Module&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @google/design.md &lt;span class="nb"&gt;export &lt;/span&gt;DESIGN.md &lt;span class="nt"&gt;--format&lt;/span&gt; json-tailwind &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; tailwind.config.js
npx @google/design.md &lt;span class="nb"&gt;export &lt;/span&gt;DESIGN.md &lt;span class="nt"&gt;--format&lt;/span&gt; css-tailwind &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; tailwind.css
npx @google/design.md &lt;span class="nb"&gt;export &lt;/span&gt;DESIGN.md &lt;span class="nt"&gt;--format&lt;/span&gt; dtcg &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; design-tokens.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You only have to focus on design.md, then export to Tailwind / CSS / DTCG. Frontend, designers, and AI Coding tools all use the same source of truth.&lt;/p&gt;

&lt;h3&gt;
  
  
  spec: hand the spec to the AI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @google/design.md spec
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Outputs design.md's own format spec. Hand that to Claude Code / Cursor / Copilot and tell it "please follow this spec when reading my DESIGN.md". The AI then knows how to parse the YAML schema, that token references use &lt;code&gt;{path.to.token}&lt;/code&gt; syntax, what's required, what's optional. Add &lt;code&gt;--rules&lt;/code&gt; and it'll output the linting rules as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using it with AI Coding tools
&lt;/h2&gt;

&lt;p&gt;The whole design goal is "turn the UI design system into something that can be continuously understood by AI", so the usage is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Put &lt;code&gt;DESIGN.md&lt;/code&gt; in your project root.&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;CLAUDE.md&lt;/code&gt; / &lt;code&gt;AGENTS.md&lt;/code&gt; / &lt;code&gt;.cursor/rules/*.mdc&lt;/code&gt;, add a line: &lt;em&gt;"For UI-related tasks, please read &lt;code&gt;DESIGN.md&lt;/code&gt; first and strictly follow the tokens and design rationale inside."&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;One reminder at the end, kind of an old chestnut:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't stuff design.md with irrelevant junk.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The whole design philosophy is to give the AI a &lt;em&gt;distilled&lt;/em&gt; version of your design knowledge — same direction as &lt;a href="https://israynotarray.com/en/ai/2026/01/20/agent-skills-vs-mcp-token-efficient/" rel="noopener noreferrer"&gt;Agent Skills&lt;/a&gt;. Give the AI the key points, not everything.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Right now, design.md doesn't ship with official integration examples for Claude Code / Cursor / Copilot — only the CLI and TypeScript API. So you need to guide the AI to read design.md via your CLAUDE.md / AGENTS.md / rules file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;So what is design.md, really?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A design system document for AI Coding tools, in a "YAML token + Markdown design rationale" format.&lt;/li&gt;
&lt;li&gt;The pain point it solves is AI-generated UI having inconsistent colours, font sizes, and spacing.&lt;/li&gt;
&lt;li&gt;The built-in CLI can lint (with WCAG contrast checks), diff, export to Tailwind / DTCG, and output a spec for the AI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hope this helps you fix the "AI generates UI with inconsistent colours, font sizes, and spacing" pain so your AI Coding workflow goes a lot more smoothly.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>designsystem</category>
      <category>claude</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Which AI Coding Tool Should You Pick in 2026? Copilot vs Cursor vs Claude Code vs Kiro vs Antigravity</title>
      <dc:creator>Ray</dc:creator>
      <pubDate>Tue, 23 Jun 2026 01:43:30 +0000</pubDate>
      <link>https://dev.to/isray_notarray/which-ai-coding-tool-should-you-pick-in-2026-copilot-vs-cursor-vs-claude-code-vs-kiro-vs-3eo3</link>
      <guid>https://dev.to/isray_notarray/which-ai-coding-tool-should-you-pick-in-2026-copilot-vs-cursor-vs-claude-code-vs-kiro-vs-3eo3</guid>
      <description>&lt;p&gt;If you've been using AI to write code, you've probably noticed that in 2026 there are more tools out there than ever — GitHub Copilot, Cursor that came later, Anthropic's Claude Code, AWS's Kiro, and Google's Antigravity. Each one is positioned a little differently, but a lot of people get tripped up trying to figure out which one is which.&lt;/p&gt;

&lt;p&gt;Personally I mostly use VSCode with GitHub Copilot and Claude Code, and I've poked around with Cursor, Kiro, and Antigravity. Friends keep asking me which one they should pick, so this is my attempt at walking through the differences across all five so you can make the call based on your own workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  A quick intro to all five tools
&lt;/h2&gt;

&lt;p&gt;Before the comparison, a fast pass on what each one actually does.&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Copilot
&lt;/h3&gt;

&lt;p&gt;GitHub Copilot is the AI coding assistant from GitHub (Microsoft). It launched back in 2021, which makes it kind of the OG of AI coding tools. It's integrated into VSCode and most major IDEs, and the core feature is real-time code completion and suggestions.&lt;/p&gt;

&lt;p&gt;After 2025 Copilot changed quite a bit. Inside VSCode it now has &lt;strong&gt;Agent Mode&lt;/strong&gt;, which can search across your codebase, modify multiple files, and run terminal commands automatically.&lt;/p&gt;

&lt;p&gt;On top of that, GitHub released &lt;strong&gt;Copilot Coding Agent&lt;/strong&gt;, which is a separate thing from Agent Mode. Coding Agent runs in a cloud environment on GitHub Actions — assign an Issue to Copilot or click "Send to Copilot Coding Agent" in chat, and it goes off and finishes the task in the background, then opens a PR for you to review. It even runs its own code review and security scan first (including Secret Scanning and dependency vulnerability checks), and only hands the PR over once those pass.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cursor
&lt;/h3&gt;

&lt;p&gt;Cursor is a code editor built around AI from the ground up. It's a fork of VSCode under the hood, so if you're already a VSCode user the switch is basically zero learning curve.&lt;/p&gt;

&lt;p&gt;Cursor understands your entire codebase, and its Agent Mode can search files, run terminal commands, and edit across multiple files automatically. In 2026 Cursor also rolled out &lt;strong&gt;Background Agents&lt;/strong&gt;, which clone your repo to the cloud and work on a separate branch — and you can spin up multiple agents to work on different tasks in parallel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Claude Code
&lt;/h3&gt;

&lt;p&gt;Claude Code is Anthropic's CLI (command-line interface) AI dev tool. Unlike the previous two, Claude Code isn't an editor or an editor plugin — it's a standalone terminal tool.&lt;/p&gt;

&lt;p&gt;Basically, you open a terminal, type &lt;code&gt;claude&lt;/code&gt;, and it starts understanding your project structure and can read, modify, and create files for you, even running commands. What makes Claude Code special is its support for Hooks, Skills, MCP Server, Channels, and other advanced features that let you compose all kinds of automated workflows around your needs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're new to Claude Code, you might want to start with my earlier post &lt;a href="https://israynotarray.com/en/ai/2026/01/28/want-to-develop-with-claude-code-beginner-to-advanced/" rel="noopener noreferrer"&gt;Want to develop with Claude Code? This guide takes you from beginner to advanced&lt;/a&gt; — it has a much more detailed walkthrough.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Kiro
&lt;/h3&gt;

&lt;p&gt;Kiro is AWS's AI dev tool. It's also a VSCode fork and it runs on top of Amazon Bedrock. The thing that sets Kiro apart from the rest is that it's built around &lt;strong&gt;Spec-Driven Development&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before Kiro writes a single line of code, it first generates a complete spec document — requirements, system design, data models, task breakdown — and only starts implementing once you've signed off on it. The upside is every piece of code can be traced back to a specific requirement, which is genuinely useful if your project needs proper documentation.&lt;/p&gt;

&lt;p&gt;Kiro also has its own &lt;strong&gt;Agent Hooks&lt;/strong&gt; that can trigger an AI Agent automatically on file save, create, or delete events — handy for things like auto-formatting, doc updates, or running git commits. And Kiro's default &lt;strong&gt;Auto Agent&lt;/strong&gt; mixes different models with caching and other optimizations to balance performance against credit consumption.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Antigravity
&lt;/h3&gt;

&lt;p&gt;Google Antigravity is the AI development platform Google launched in November 2025 alongside Gemini 3. The base is also a VSCode fork, but the changes are extensive enough that it feels pretty different from regular VSCode.&lt;/p&gt;

&lt;p&gt;Antigravity goes hard on the &lt;strong&gt;Agent-First&lt;/strong&gt; approach. It has two main surfaces: a traditional Editor View where you write code, and a &lt;strong&gt;Manager Surface&lt;/strong&gt;, where you can dispatch multiple agents to work asynchronously across different workspaces, watching each agent's progress in real time.&lt;/p&gt;

&lt;p&gt;Once an agent finishes a task, it produces an &lt;strong&gt;artifact report&lt;/strong&gt; — task list, implementation plan, screenshots, even browser recordings — so you can see what it actually did. Model-wise, beyond Google's own Gemini 3.1 Pro and Gemini 3 Flash, it also supports Claude Sonnet 4.6, Claude Opus 4.6, and GPT-OSS-120B.&lt;/p&gt;

&lt;p&gt;That said, Antigravity is still iterating fast right now. Rate limits and pricing are in flux, so check the official site for the latest before you commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core feature comparison
&lt;/h2&gt;

&lt;p&gt;Now that you know what each tool does at a high level, here's how they compare on core features.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;GitHub Copilot&lt;/th&gt;
&lt;th&gt;Cursor&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;th&gt;Kiro&lt;/th&gt;
&lt;th&gt;Antigravity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Code completion&lt;/td&gt;
&lt;td&gt;Real-time inline&lt;/td&gt;
&lt;td&gt;Real-time inline + Tab prediction&lt;/td&gt;
&lt;td&gt;No real-time completion&lt;/td&gt;
&lt;td&gt;Real-time inline&lt;/td&gt;
&lt;td&gt;Real-time inline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chat&lt;/td&gt;
&lt;td&gt;Copilot Chat&lt;/td&gt;
&lt;td&gt;Built-in chat&lt;/td&gt;
&lt;td&gt;CLI chat&lt;/td&gt;
&lt;td&gt;Built-in chat&lt;/td&gt;
&lt;td&gt;Built-in chat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-file editing&lt;/td&gt;
&lt;td&gt;Yes (Agent Mode)&lt;/td&gt;
&lt;td&gt;Yes (Composer)&lt;/td&gt;
&lt;td&gt;Native&lt;/td&gt;
&lt;td&gt;Yes (Agent Mode)&lt;/td&gt;
&lt;td&gt;Yes (Multi-Agent)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Codebase understanding&lt;/td&gt;
&lt;td&gt;Needs &lt;a class="mentioned-user" href="https://dev.to/workspace"&gt;@workspace&lt;/a&gt;
&lt;/td&gt;
&lt;td&gt;Auto-indexed&lt;/td&gt;
&lt;td&gt;Auto-scanned&lt;/td&gt;
&lt;td&gt;Auto-indexed&lt;/td&gt;
&lt;td&gt;Auto-indexed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Terminal integration&lt;/td&gt;
&lt;td&gt;Inside VSCode only&lt;/td&gt;
&lt;td&gt;Inside Cursor only&lt;/td&gt;
&lt;td&gt;Native terminal&lt;/td&gt;
&lt;td&gt;Inside Kiro only&lt;/td&gt;
&lt;td&gt;Inside Antigravity only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP Server&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom rules file&lt;/td&gt;
&lt;td&gt;copilot-instructions.md&lt;/td&gt;
&lt;td&gt;.cursor/rules/*.mdc&lt;/td&gt;
&lt;td&gt;CLAUDE.md&lt;/td&gt;
&lt;td&gt;Steering Files&lt;/td&gt;
&lt;td&gt;Not specified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Background tasks&lt;/td&gt;
&lt;td&gt;Yes (via GitHub Actions)&lt;/td&gt;
&lt;td&gt;Yes (cloud async)&lt;/td&gt;
&lt;td&gt;Yes (terminal background)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (multi-agent dispatch)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remote control&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (Channels / Remote Control)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Built-in spec generation&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (Spec-Driven)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-model support&lt;/td&gt;
&lt;td&gt;Yes (Claude, GPT, etc.)&lt;/td&gt;
&lt;td&gt;Yes (Claude, GPT, Gemini, etc.)&lt;/td&gt;
&lt;td&gt;Claude family only&lt;/td&gt;
&lt;td&gt;Claude family only (via Bedrock)&lt;/td&gt;
&lt;td&gt;Yes (Gemini, Claude, GPT-OSS)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What the table tells you is that the five tools are converging on features, but each has a clear strength.&lt;/p&gt;

&lt;p&gt;In short — Copilot leans on inline completion and GitHub ecosystem integration, Cursor focuses on the editor-native AI experience, Claude Code goes the terminal automation route, Kiro centers on Spec-Driven Development, and Antigravity wraps everything around an Agent-First multi-model architecture. None of them is objectively "better" — it really depends on which one fits your workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing breakdown
&lt;/h2&gt;

&lt;p&gt;Pricing matters to most people, so here's the snapshot for March 2026:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;GitHub Copilot&lt;/th&gt;
&lt;th&gt;Cursor&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;th&gt;Kiro&lt;/th&gt;
&lt;th&gt;Antigravity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;2,000 completions + 50 chat requests/month&lt;/td&gt;
&lt;td&gt;2,000 completions + 50 slow requests/month&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;50 credits/month&lt;/td&gt;
&lt;td&gt;Yes (stricter rate limit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Personal entry&lt;/td&gt;
&lt;td&gt;$10/mo (Pro, 300 premium requests)&lt;/td&gt;
&lt;td&gt;$20/mo (Pro)&lt;/td&gt;
&lt;td&gt;$20/mo (Claude Pro, limited usage)&lt;/td&gt;
&lt;td&gt;$20/mo (Pro, 1,000 credits)&lt;/td&gt;
&lt;td&gt;$20/mo (AI Pro)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Personal advanced&lt;/td&gt;
&lt;td&gt;$39/mo (Pro+, 1,500 premium requests)&lt;/td&gt;
&lt;td&gt;$60/mo (Pro+, 3x usage) / $200/mo (Ultra, 20x usage)&lt;/td&gt;
&lt;td&gt;$100/mo (Max 5x) / $200/mo (Max 20x)&lt;/td&gt;
&lt;td&gt;$40/mo (Pro+, 2,000 credits) / $200/mo (Power, 10,000 credits)&lt;/td&gt;
&lt;td&gt;$249.99/mo (AI Ultra)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team&lt;/td&gt;
&lt;td&gt;$19/mo/user (Business)&lt;/td&gt;
&lt;td&gt;$40/mo/user (Teams)&lt;/td&gt;
&lt;td&gt;Per Team / Enterprise plan&lt;/td&gt;
&lt;td&gt;Per enterprise plan&lt;/td&gt;
&lt;td&gt;Per enterprise plan&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Pricing follows each vendor's official site and can change at any time. GitHub Copilot also offers free Pro access for verified students and open source contributors.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And a quick word on each tool's billing model, because they all count things differently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt; bills in Premium Requests — the number of times you hit the high-end models (Claude Opus 4.6, o3, etc.). Pro gets 300/month, Pro+ gets 1,500. Once you blow through the quota, Copilot doesn't cut you off — it falls back to the included base model (like GPT-4.1), but response quality drops noticeably. If you don't want the downgrade you can set an overage budget at $0.04 per request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cursor&lt;/strong&gt; gives every paid plan a credit pool. Pro+ has 3x the usage of Pro, Ultra has 20x. If you let Cursor pick the model automatically (Auto mode), it doesn't burn credits — effectively unlimited. If you manually pick a specific model (say Claude Sonnet 4.6), that comes out of the credit pool. Once you're out of credits, you can still use Auto mode, you just lose manual model selection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Code&lt;/strong&gt; is bundled into Claude's subscription. Max comes in 5x ($100/mo) and 20x ($200/mo) — the multiplier is relative to Pro, meaning how much more you can do before hitting limits. Max also covers the Claude desktop app, mobile app, and Claude Code together, which makes sense if you also use Claude for non-coding things (writing docs, research, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kiro&lt;/strong&gt; uses a unified &lt;strong&gt;credit system&lt;/strong&gt; — every operation pulls from the same pool, billed by prompt complexity. A simple edit might be under 1 credit, while complex tasks cost more. Kiro's Auto Agent mixes models automatically and runs about 23% cheaper than manually picking Sonnet 4 for the same workload — that's why it's the default. Overage is $0.04 per credit, but it's off by default; you have to opt in via settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Antigravity&lt;/strong&gt; is bundled into Google's AI subscription tiers (AI Pro and AI Ultra). You can also buy AI Credits separately at $25 per 2,500 credits. The pricing and quota strategy is still being adjusted, so double-check the official site before signing up.&lt;/p&gt;

&lt;h2&gt;
  
  
  So which one fits which scenario?
&lt;/h2&gt;

&lt;p&gt;If you're still not sure which to pick after all that, let me sort them by use case.&lt;/p&gt;

&lt;h3&gt;
  
  
  You mainly care about the feel of writing code
&lt;/h3&gt;

&lt;p&gt;If your day is mostly writing code and you want a fast, always-on assistant by your side, &lt;strong&gt;GitHub Copilot&lt;/strong&gt; is probably the best fit. Its inline completion is still the smoothest of the bunch, the VSCode integration is the deepest, and it has matching AI features for PR review and Issue triage too — especially handy if your team is already deep into the GitHub ecosystem.&lt;/p&gt;

&lt;p&gt;Plus, Coding Agent can handle background tasks and open PRs for you automatically, which is fantastic for team collaboration.&lt;/p&gt;

&lt;h3&gt;
  
  
  You want an AI experience inside the editor
&lt;/h3&gt;

&lt;p&gt;If you do a lot of cross-file refactoring or you want the entire editor experience designed around AI, &lt;strong&gt;Cursor&lt;/strong&gt; is the way. Composer handles multi-file edits really well, and it supports multiple AI models (Claude, GPT, Gemini, etc.) so you can pick the model that fits the task.&lt;/p&gt;

&lt;p&gt;Frontend work is a great example — one feature often touches a bunch of files (component, styles, routes, tests), and Composer chews through all of it in one go. Background Agents also let you spin up multiple agents in parallel in the cloud.&lt;/p&gt;

&lt;h3&gt;
  
  
  You want deep automation and customization
&lt;/h3&gt;

&lt;p&gt;If you live in the terminal or you need next-level automation and customization, &lt;strong&gt;Claude Code&lt;/strong&gt; is the pick. The combination of Hooks, Skills, and Channels lets you compose all sorts of automated workflows.&lt;/p&gt;

&lt;p&gt;For example, you can wire up Hooks to run security checks before every command Claude Code executes, or use Skills to package your team's code review conventions as a reusable skill set. Pair it with Git Worktree and you can even run multiple Claude Code agents on the same project, each handling a different task.&lt;/p&gt;

&lt;p&gt;Channels in particular is something the other tools can't really match — you can send messages directly to a running Claude Code session over Telegram or Discord, let it work on the task in the background, and have the result delivered back to your phone.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If Channels sounds interesting, I wrote a full setup walkthrough here: &lt;a href="https://israynotarray.com/en/ai/2026/03/20/claude-code-channels-instead-of-openclaw/" rel="noopener noreferrer"&gt;Don't want to use the lobster (OpenClaw)? Try Claude Code Channels&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Your project needs strict documentation and spec management
&lt;/h3&gt;

&lt;p&gt;If you're working on a project that requires complete documentation — client work, internal enterprise systems, anything that needs to pass an audit — &lt;strong&gt;Kiro&lt;/strong&gt;'s Spec-Driven Development fits perfectly.&lt;/p&gt;

&lt;p&gt;Before any code gets written, Kiro produces requirements, system design, and a task breakdown, and every chunk of code traces back to a specific requirement. The upfront cost is higher, but in exchange your project has solid documentation from day one — maintenance and handoffs get a lot easier.&lt;/p&gt;

&lt;p&gt;And since Kiro runs on AWS, if your team is already on Lambda, CDK, CloudFormation, or other AWS services, the integration is much smoother than the alternatives.&lt;/p&gt;

&lt;h3&gt;
  
  
  You want an Agent-First development experience
&lt;/h3&gt;

&lt;p&gt;If you want to play with multiple AI agents working for you in parallel, &lt;strong&gt;Google Antigravity&lt;/strong&gt; is worth a try. Manager Surface lets you dispatch multiple agents to different workspaces, and once they finish a task they produce an artifact report you can review.&lt;/p&gt;

&lt;p&gt;The model lineup is also varied — beyond Google's own Gemini family, you can also use the Claude lineup and GPT-OSS series.&lt;/p&gt;

&lt;p&gt;That said, like I mentioned earlier, even though Antigravity is a VSCode fork, the UI changes are extensive enough that it feels pretty different from regular VSCode, and it's still iterating fast — so factor that in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 2026 main event: AI Agent capability
&lt;/h2&gt;

&lt;p&gt;In 2026 the competition has shifted from code completion to AI Agent capability. The basic idea is: AI shouldn't just answer your questions, it should be able to plan, execute, and even self-correct to finish an entire task on its own.&lt;/p&gt;

&lt;p&gt;Here's how the five tools stack up on Agent capability:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent capability&lt;/th&gt;
&lt;th&gt;GitHub Copilot&lt;/th&gt;
&lt;th&gt;Cursor&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;th&gt;Kiro&lt;/th&gt;
&lt;th&gt;Antigravity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;In-editor agent&lt;/td&gt;
&lt;td&gt;Yes (Agent Mode)&lt;/td&gt;
&lt;td&gt;Yes (Agent Mode)&lt;/td&gt;
&lt;td&gt;Yes (VSCode plugin)&lt;/td&gt;
&lt;td&gt;Yes (Agent Mode)&lt;/td&gt;
&lt;td&gt;Yes (Editor View)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Background tasks&lt;/td&gt;
&lt;td&gt;Yes (via GitHub Actions)&lt;/td&gt;
&lt;td&gt;Yes (cloud async)&lt;/td&gt;
&lt;td&gt;Yes (terminal background)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (multi-agent dispatch)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-agent parallel&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (with Git Worktree)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (multi-workspace)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Event-driven automation&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (Hooks)&lt;/td&gt;
&lt;td&gt;Yes (Agent Hooks)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auto code review&lt;/td&gt;
&lt;td&gt;Yes (built into Coding Agent)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (auto-validation)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auto security scan&lt;/td&gt;
&lt;td&gt;Yes (Secret / Dependency)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spec generation&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Artifact report output&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (plan, screenshots, recording)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;External chat platform integration&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (Channels)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The basic Agent features are now table stakes for everyone — the real differences are in the advanced features, and which direction each tool has taken. Pick whichever one matches your needs.&lt;/p&gt;

&lt;p&gt;One thing worth calling out: Claude Code and Kiro both have the concept of event-driven automation, but they implement it differently. Claude Code Hooks fire before and after tool execution — useful for safety checks, formatting, that kind of thing. Kiro's Agent Hooks trigger on file events (save, create, delete) and you describe them in natural language, which is a lower bar to entry.&lt;/p&gt;

&lt;h2&gt;
  
  
  My own workflow
&lt;/h2&gt;

&lt;p&gt;After all that, you might be wondering what I actually use day-to-day.&lt;/p&gt;

&lt;p&gt;I mostly use VSCode with GitHub Copilot and Claude Code, and the workflow looks roughly like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Day-to-day coding&lt;/strong&gt; — GitHub Copilot's inline completion handles the bulk of it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature work or refactoring&lt;/strong&gt; — I open Claude Code and let it plan and handle the cross-file edits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anything that needs automation&lt;/strong&gt; — also Claude Code, paired with Hooks and Skills to keep output quality consistent&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I've touched all five — GitHub Copilot, Claude Code, Cursor, Kiro, Antigravity. Cursor's editor experience is genuinely solid, but I'm too deep into the VSCode ecosystem at this point, and the Copilot + Claude Code combo covers most of what I need, so VSCode stays as my main driver.&lt;/p&gt;

&lt;p&gt;If your budget only allows for one, here's my take:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New to AI coding → &lt;strong&gt;GitHub Copilot&lt;/strong&gt; (the free plan is plenty, students get free Pro)&lt;/li&gt;
&lt;li&gt;Want the best editor-native AI experience → &lt;strong&gt;Cursor&lt;/strong&gt; (Composer is great for cross-file edits, Background Agents are powerful too)&lt;/li&gt;
&lt;li&gt;Prefer terminal or need deep automation → &lt;strong&gt;Claude Code&lt;/strong&gt; (also has a VSCode extension; Hooks + Skills + Channels is a flexible combo)&lt;/li&gt;
&lt;li&gt;Project needs full spec docs → &lt;strong&gt;Kiro&lt;/strong&gt; (Spec-Driven Development takes you from spec to implementation in one flow)&lt;/li&gt;
&lt;li&gt;Curious about Agent-First development → &lt;strong&gt;Google Antigravity&lt;/strong&gt; (free plan is enough to play with)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Whichever one you end up picking, one thing stays true: &lt;strong&gt;A better tool is still just a tool. Your domain knowledge and judgment are what really matter — even with all the driver assists in the world, you still need to understand the car, the road, and the rules.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI coding tools can help you write code faster, but they won't make decisions for you, and they won't take responsibility for the outcome.&lt;/p&gt;

&lt;p&gt;So when you're using these tools, keep your critical thinking on. Review what they suggest, test it, and make sure the final code is safe and reliable.&lt;/p&gt;

&lt;p&gt;Hopefully this helps you find the AI coding tool that fits your workflow best — see you in the next post.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>githubcopilot</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How Much of Your Blog Does AI Search Actually Grab? Breaking Down Claude's WebSearch and WebFetch</title>
      <dc:creator>Ray</dc:creator>
      <pubDate>Fri, 19 Jun 2026 14:23:46 +0000</pubDate>
      <link>https://dev.to/isray_notarray/how-much-of-your-blog-does-ai-search-actually-grab-breaking-down-claudes-websearch-and-webfetch-538f</link>
      <guid>https://dev.to/isray_notarray/how-much-of-your-blog-does-ai-search-actually-grab-breaking-down-claudes-websearch-and-webfetch-538f</guid>
      <description>&lt;p&gt;A while back I wrote &lt;a href="https://israynotarray.com/en/ai/2026/04/08/aeo-answer-engine-optimization-guide/" rel="noopener noreferrer"&gt;Is SEO Not Enough? Meet AEO — Getting Your Site Found by AI Search&lt;/a&gt;, and right after finishing it a question hit me: when AI does a web search, how much of my blog does it actually grab? The whole article verbatim? The first 500 characters? Or does it bail after seeing just the title? So I dug into it, and this post walks through Anthropic's official &lt;code&gt;web_search&lt;/code&gt; and &lt;code&gt;web_fetch&lt;/code&gt; tool specs, runs a quick test against my own blog, and ends with what all this concretely means for how you should write posts and copy.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Search" and "fetch" are two different things
&lt;/h2&gt;

&lt;p&gt;Before going further, the one thing worth being crystal clear on: when AI runs a query, &lt;strong&gt;"search"&lt;/strong&gt; and &lt;strong&gt;"fetching the page body"&lt;/strong&gt; are not the same operation. They're two separate stages.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stage 1 (WebSearch):&lt;/strong&gt; the AI takes your question and calls the WebSearch tool (which hits a search engine). What comes back is a list of search results — each entry has things like URL and title, but no page body.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stage 2 (WebFetch):&lt;/strong&gt; after looking at the search result list, the AI decides which entries are worth digging into, then fires a WebFetch request at each of those URLs, basically saying "give me the body of this page." That's when actual content gets pulled in.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why doesn't it just grab the body during the search stage? Context window limits. If every search shoved 10 results' worth of full bodies in, your usable context would blow up fast — and then you'd start complaining the AI is dumb and forgets what you just asked it (because the context did overflow). So it's split into two stages: search first for a list, then decide which entries from that list to actually fetch.&lt;/p&gt;

&lt;p&gt;Once that two-stage split makes sense, the rest of this post is about what each stage actually pulls in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does WebSearch pull in?
&lt;/h2&gt;

&lt;p&gt;Going straight to Anthropic's official &lt;code&gt;web_search&lt;/code&gt; tool docs — every search result entry has only four fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;url&lt;/code&gt;: the page URL&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;title&lt;/code&gt;: the page title&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;page_age&lt;/code&gt;: when the page was last updated&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;encrypted_content&lt;/code&gt;: encrypted content, not for the AI to read the article — it's for multi-turn conversation citations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. Four fields.&lt;/p&gt;

&lt;p&gt;What the AI sees during the search stage is "URL, title, last updated" — three pieces of human-readable info. No body content at all.&lt;/p&gt;

&lt;p&gt;What if the AI cites your content? There's a cap on that too:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Each &lt;code&gt;web_search_result_location&lt;/code&gt;'s &lt;code&gt;cited_text&lt;/code&gt; is &lt;strong&gt;up to 150 characters of the cited content&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In short: at most 150 characters of quoted text. And that's just the API-level spec.&lt;/p&gt;

&lt;p&gt;Claude Code's built-in WebSearch shaves it down further. According to Mikhail Shilkov's &lt;a href="https://mikhail.io/2025/10/claude-code-web-tools/" rel="noopener noreferrer"&gt;breakdown of Claude Code's internal behavior&lt;/a&gt;, Claude Code even drops &lt;code&gt;page_age&lt;/code&gt; and &lt;code&gt;encrypted_content&lt;/code&gt;, keeping only &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;url&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So basically — at the search stage, the AI sees nothing more than &lt;strong&gt;one title and one URL&lt;/strong&gt; from your site. That's it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does WebFetch pull in?
&lt;/h2&gt;

&lt;p&gt;Now for when the body actually gets pulled in — Stage 2, WebFetch.&lt;/p&gt;

&lt;p&gt;Once the AI has the search results, if it decides to open up a few entries, it fires one WebFetch request per URL, and that's when the full body comes back. How much of it?&lt;/p&gt;

&lt;p&gt;This needs to be split into two layers, because the API and Claude Code work differently.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
When I say "API" here, I mean the Anthropic API's &lt;code&gt;web_fetch&lt;/code&gt; tool. "Claude Code" means the WebFetch feature built into Anthropic's own product. The two have different specs and flows.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  API-level web_fetch
&lt;/h3&gt;

&lt;p&gt;The Anthropic API's &lt;code&gt;web_fetch&lt;/code&gt; tool has a parameter called &lt;code&gt;max_content_tokens&lt;/code&gt; that developers can set themselves — though the official docs use 100,000 tokens in their examples.&lt;/p&gt;

&lt;p&gt;The docs also give a reference conversion:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Content size&lt;/th&gt;
&lt;th&gt;Estimated tokens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Average web page 10 KB&lt;/td&gt;
&lt;td&gt;~2,500 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large doc page 100 KB&lt;/td&gt;
&lt;td&gt;~25,000 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Research paper PDF 500 KB&lt;/td&gt;
&lt;td&gt;~125,000 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So a medium-length blog post in plain text is usually 1–2,000 tokens, way below the 100K ceiling. Truncation basically isn't a concern unless you wrote a 50,000-character monster.&lt;/p&gt;

&lt;p&gt;One thing to note: &lt;code&gt;web_fetch&lt;/code&gt;'s citation works differently from &lt;code&gt;web_search&lt;/code&gt;. It uses &lt;code&gt;start_char_index&lt;/code&gt; / &lt;code&gt;end_char_index&lt;/code&gt; to pick out a specific position in the article (although the docs don't pin down a hard character limit).&lt;/p&gt;

&lt;h3&gt;
  
  
  Claude Code's built-in WebFetch
&lt;/h3&gt;

&lt;p&gt;Claude Code's built-in WebFetch goes a different route.&lt;/p&gt;

&lt;p&gt;Per Mikhail Shilkov's breakdown, the WebFetch flow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Convert HTML to Markdown using the Turndown package&lt;/li&gt;
&lt;li&gt;Extract the first 100 KB of plain text&lt;/li&gt;
&lt;li&gt;Pass that 100 KB to the Haiku 3.5 model&lt;/li&gt;
&lt;li&gt;Haiku summarizes the answer based on your prompt and returns the summary to the main model&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The real kicker is step 3. The main model — the Claude model you're actually using — never sees the page's original text. It only sees the version Haiku summarized. Which means &lt;strong&gt;what your writing turns into by the time it reaches the main model is decided by how Haiku reads it, not by how much you wrote&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The citation has a limit too. The rule Mikhail extracted from Claude Code's internal prompt is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Enforce a strict 125-character maximum for quotes from any source document.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So quotes max out at 125 characters.&lt;/p&gt;

&lt;p&gt;You're probably wondering — so how much is 100 KB of plain text? For Chinese, where each character is roughly 3 bytes, 100 KB fits 30,000+ characters; for English at 1 byte per character, that's well over 100,000 characters. No regular blog post is going to hit that ceiling. So the real concern should be "how do I get Haiku to extract the parts I want to be quoted," not "how much content am I feeding Haiku."&lt;/p&gt;

&lt;h2&gt;
  
  
  Running a real test against my own blog
&lt;/h2&gt;

&lt;p&gt;Enough theory — let's actually test it.&lt;/p&gt;

&lt;p&gt;I had Claude call the WebFetch tool against my blog's homepage (&lt;code&gt;israynotarray.com&lt;/code&gt;) and asked it to grab the body.&lt;/p&gt;

&lt;p&gt;To make this measurable, I leaned on Claude Code's Hook feature to log every stage's input and output. Here's the hook config — every WebSearch and WebFetch I/O gets logged:&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;"hooks"&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;"PostToolUse"&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;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"WebSearch|WebFetch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&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;"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;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/claude-tools/hooks/log-web-tool.sh"&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;span class="nl"&gt;"SessionEnd"&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;"hooks"&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;"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;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/claude-tools/hooks/dump-transcript.sh"&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;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;The prompt I used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Please use the WebFetch tool to grab the content of israynotarray.com's homepage, then tell me what you extracted from that page.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The actual input passed to WebFetch:&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;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://israynotarray.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"prompt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Tell me the main content of this homepage: site name, author bio, latest article list (titles and summaries), categories, plus any navbar or sidebar info."&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;After it ran, the WebFetch result — the summary that came back — looked roughly like this:&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;"bytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1068&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"codeText"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OK"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"# Page Content Analysis&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Based on the content snippet provided, I can share the following:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;## Site Structure&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;- **Main category**: AI-related content, including Gemini and Gemini Omni products&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;## Latest Article&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;**Title**: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Gemini Omni Video Generation: 30 Prompt Templates for Reels, Product Demos, and Logo Reveals&lt;/span&gt;&lt;span class="se"&gt;\"\n\n&lt;/span&gt;&lt;span class="s2"&gt;**Summary**:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;This post introduces Gemini Omni video generation, released by Google at I/O in May 2026, and explains how it replaces the earlier Veo 3.1. The article covers new features like '10-second clips, native synced audio, and Chinese text rendering,' and provides 30 practical prompt templates for use cases including Instagram Reels, product demos, logo animations, B-roll, transitions, quote cards, lifestyle, and food and travel.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;**Publish date**: 2026-06-06  &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;**Reading time**: ~23 min&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;## Limitations&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;The content snippet provided does not include author bio or full navbar info."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"durationMs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4603&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://israynotarray.com"&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;See it? What the AI actually pulled from my blog is just this tiny under-1,000-character summary. A whole website obviously contains way more than this — the rest was never seen by the main model. The Haiku middle layer reads the page and only extracts what it judges relevant to my prompt. If I opened the same page in a browser, I'd see a full grid of article cards plus a sidebar — but Haiku doesn't ship the full grid back.&lt;/p&gt;

&lt;p&gt;I also tried an older post with a deliberately broken URL path, and got this:&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;"bytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;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;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"codeText"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Not Found"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The server returned HTTP 404 Not Found.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;The response body was not retrieved. If this URL requires authentication, use an authenticated tool (e.g. `gh` for GitHub, or an MCP-provided fetch tool) instead of WebFetch."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"durationMs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;588&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://israynotarray.com/dqwdqwdqwd"&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;Even the content of your 404 page is invisible to the AI — WebFetch just reports the 404 and the AI has no way to see what your 404 page says. Which means if your site has path issues, you've refactored URLs, or you only have frontend routing without real pages, the AI can't pull anything.&lt;/p&gt;

&lt;p&gt;Side note — this lines up with a caveat in Claude's official docs:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The web fetch tool currently does not support websites dynamically rendered with JavaScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If your blog is a frontend SPA where content is entirely rendered by JavaScript at runtime, what the AI grabs might just be empty-shell HTML with no articles visible. Static generators (Hexo, Astro, Next.js in SSG mode) are relatively safe, since the build output is fully rendered HTML — the AI grabs and immediately sees content.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't forget the robots.txt layer
&lt;/h2&gt;

&lt;p&gt;There's one more important piece — whether the AI can pull your site has a major prerequisite: robots.txt.&lt;/p&gt;

&lt;p&gt;AI crawlers basically split into two types: search-style (cite and link back to your site) and training-style (eat content to feed the model, not necessarily linking back). The common mapping:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Crawler&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude-SearchBot / Claude-User&lt;/td&gt;
&lt;td&gt;Search&lt;/td&gt;
&lt;td&gt;Real-time fetch when Claude answers, cites back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ClaudeBot&lt;/td&gt;
&lt;td&gt;Training&lt;/td&gt;
&lt;td&gt;Fetches content to feed Claude training&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OAI-SearchBot / ChatGPT-User&lt;/td&gt;
&lt;td&gt;Search&lt;/td&gt;
&lt;td&gt;Real-time fetch when ChatGPT answers, cites back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPTBot&lt;/td&gt;
&lt;td&gt;Training&lt;/td&gt;
&lt;td&gt;Fetches content to feed GPT training&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PerplexityBot&lt;/td&gt;
&lt;td&gt;Search&lt;/td&gt;
&lt;td&gt;Used by Perplexity engine, cites back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google-Extended&lt;/td&gt;
&lt;td&gt;Training&lt;/td&gt;
&lt;td&gt;For Gemini training&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CCBot&lt;/td&gt;
&lt;td&gt;Training&lt;/td&gt;
&lt;td&gt;Common Crawl public dataset&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you want to be cited by AI but don't want your content used for training, the most common strategy is "allow search-style, block training-style."&lt;/p&gt;

&lt;p&gt;Here's a robots.txt template you can copy-paste:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Search-style AI crawlers: allow (they cite back)
User-agent: OAI-SearchBot
Allow: /

User-agent: ChatGPT-User
Allow: /

User-agent: Claude-SearchBot
Allow: /

User-agent: Claude-User
Allow: /

User-agent: PerplexityBot
Allow: /

# Training-style AI crawlers: block (consume data without citing)
User-agent: GPTBot
Disallow: /

User-agent: ClaudeBot
Disallow: /

User-agent: Google-Extended
Disallow: /

User-agent: CCBot
Disallow: /

User-agent: Bytespider
Disallow: /

# Content signal: searchable but not for training, not for direct AI input
Content-Signal: ai-train=no, search=yes, ai-input=no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a full Agent Readiness setup to score 100, see &lt;a href="https://israynotarray.com/en/ai/2026/04/21/from-3-to-100-isitagentready-readiness-guide/" rel="noopener noreferrer"&gt;From 3 to 100! How to Get Your Site to Pass isitagentready's AI Agent Readiness Check&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what does this concretely mean for writing?
&lt;/h2&gt;

&lt;p&gt;Once you understand all the constraints above, there are four things worth specifically working on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Titles need to stand on their own
&lt;/h3&gt;

&lt;p&gt;At the search stage, all the AI sees about your article is two fields — title and URL.&lt;/p&gt;

&lt;p&gt;If your title needs a subtitle or context to make sense, when the AI lines it up against ten other results it'll get skipped.&lt;/p&gt;

&lt;p&gt;A quick comparison:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Weaker: "Implementation Notes"&lt;/li&gt;
&lt;li&gt;Stronger: "Complete Implementation Notes: Content Negotiation for HTML-to-Markdown in a Cloudflare Worker"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The stronger version packs in "topic, tool, what it does, and article type" — the AI doesn't even need to open the page to know whether it's worth fetching.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lead with the answer
&lt;/h3&gt;

&lt;p&gt;At the WebFetch stage, the Haiku middle layer reads top-down. The first 300–500 characters decide what it summarizes back. If your opening is "Before we get into X, let's recap a bit of history…", Haiku reads halfway through and discovers the intro is all background and no answer — so it just summarizes the background.&lt;/p&gt;

&lt;p&gt;The right move is to make the first sentence of every H2 a direct conclusion, then add the context after. I covered this principle in &lt;a href="https://israynotarray.com/en/ai/2026/04/08/aeo-answer-engine-optimization-guide/" rel="noopener noreferrer"&gt;Is SEO Not Enough? Meet AEO — Getting Your Site Found by AI Search&lt;/a&gt; too — worth reading alongside this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Design single sentences that can be quoted standalone
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;cited_text&lt;/code&gt; is 150 characters on &lt;code&gt;web_search&lt;/code&gt; and 125 characters on Claude Code's built-in WebFetch. That means when the AI quotes you, the slot it has is one short sentence that "makes sense without context."&lt;/p&gt;

&lt;p&gt;Consciously design sentences like that. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Weaker: "This is a bit different from the method mentioned earlier — the main difference is…" (makes no sense without context)&lt;/li&gt;
&lt;li&gt;Stronger: "llms.txt was proposed by Answer.AI co-founder Jeremy Howard in 2024, with the goal of proactively telling AI what important content a site has." (stands on its own without surrounding text)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After writing a paragraph, pick one sentence and ask yourself: if someone who hadn't read the rest of the post saw just this sentence, would they get it? If yes, it has a shot at being quoted.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use structure as Haiku's navigation markers
&lt;/h3&gt;

&lt;p&gt;H2, H3, &lt;code&gt;-&lt;/code&gt; lists, tables, &lt;code&gt;&lt;/code&gt;`&lt;code&gt;js&lt;/code&gt; code blocks — these Markdown structures are especially useful for the middleware summary layer. When Haiku reads the Markdown converted from your HTML, it treats headings as "what this section is about" indexes, lists as "main points" signals, and tables as "supporting data" units.&lt;/p&gt;

&lt;p&gt;If your whole article is pure prose paragraphs, Haiku has no markers and has to grind through it semantically — what comes out is scattered. If you have clear structure, Haiku can summarize along the markers, and the result lines up with the points you actually want quoted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;So how much of your blog does AI search actually pull?&lt;/p&gt;

&lt;p&gt;The answer breaks down into three layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Search stage:&lt;/strong&gt; title + URL only&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Body fetch stage:&lt;/strong&gt; the API default can fit your whole article, but Claude Code goes through Haiku summarization with a 100 KB cut-off&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Citation stage:&lt;/strong&gt; &lt;code&gt;web_search&lt;/code&gt; is 150 characters, Claude Code WebFetch is 125 characters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writing for AI search means targeting those three gates — it's not about getting the AI to memorize your entire post.&lt;/p&gt;

&lt;p&gt;If your blog hasn't set up AI bot routing yet, copy the robots.txt template above to get the basics in place — the rest is just content over time.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Is AI Getting Quietly Dumber? A 24/7 Benchmark That Catches LLM Degradation</title>
      <dc:creator>Ray</dc:creator>
      <pubDate>Thu, 18 Jun 2026 03:54:54 +0000</pubDate>
      <link>https://dev.to/isray_notarray/is-ai-getting-quietly-dumber-a-247-benchmark-that-catches-llm-degradation-2g6p</link>
      <guid>https://dev.to/isray_notarray/is-ai-getting-quietly-dumber-a-247-benchmark-that-catches-llm-degradation-2g6p</guid>
      <description>&lt;p&gt;You've probably hit this before — yesterday the AI felt sharp, fixed your bug without you even asking, and threw in a few extra cleanups along the way. Then today, same kind of problem, and suddenly it refuses to touch anything you didn't explicitly point at, or starts going in circles. And you start wondering "wait, is AI getting quietly dumber?"&lt;/p&gt;

&lt;p&gt;A lot of people have this feeling but it's hard to pin down. Is the provider messing with the model? Is today's problem genuinely harder? Or is it all in your head? Without a number to point at, it just stays an urban legend.&lt;/p&gt;

&lt;p&gt;So this post is about a site called &lt;a href="https://aistupidlevel.info/" rel="noopener noreferrer"&gt;AIStupidLevel&lt;/a&gt; — the name pretty much spells it out. It runs round-the-clock tests against the major AI models and turns "is AI getting dumber" into an actual curve you can look at.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why would an AI "get dumber" in the first place?
&lt;/h2&gt;

&lt;p&gt;A reasonable pushback: doesn't the model get trained once and then frozen? A few things are actually going on behind the scenes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Silent updates.&lt;/strong&gt; If you've worked with the API, you've probably seen version strings like &lt;code&gt;gpt-4.0-20240924&lt;/code&gt; — that trailing date hints at a specific build. But when you pick a model inside Codex or similar tools, you don't see that level of detail. Some models don't even have versioned IDs, just a generic &lt;code&gt;gpt-4&lt;/code&gt;. So you can't actually tell which build you're hitting, and a silent swap is really hard to notice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quantization.&lt;/strong&gt; To handle global peak traffic and save compute, providers sometimes compress the model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Throttled compute.&lt;/strong&gt; Once usage crosses a threshold, providers may cap how much compute each user can pull, which makes outputs feel worse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compute migration.&lt;/strong&gt; When a new model is about to launch, providers sometimes shift compute away from the older model. From my own time hitting the API, this is the one I see most — the same prompt suddenly degrades overnight, then a few days later a stronger version drops, and shortly after the old version goes back to normal.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I covered quantization more thoroughly in &lt;a href="https://israynotarray.com/en/ai/2026/04/12/llm-parameters-quantization-guide/" rel="noopener noreferrer"&gt;Want to Run an LLM Yourself? Understanding Model Parameters and Quantization So You Stop Picking the Wrong Model&lt;/a&gt; — short version, it's a compression technique that saves resources but loses some detail.&lt;/p&gt;

&lt;p&gt;So an AI model isn't actually a frozen thing. Providers can silently update it, quantize it, throttle it, or migrate compute away from it — and any of those will change what you experience. The hard part is, you usually can't tell.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what is AIStupidLevel exactly?
&lt;/h2&gt;

&lt;p&gt;AIStupidLevel is a third-party benchmark platform (open source, MIT) that continuously monitors whether AI models are regressing. Think of it like a system health check, except it's checking the "health" of AI models. It runs 24/7 against &lt;strong&gt;21 production models from 7 providers&lt;/strong&gt; — OpenAI, Anthropic, Google, xAI, DeepSeek, Kimi, GLM — and turns each model's current performance into a score on a dashboard.&lt;/p&gt;

&lt;p&gt;It's not run by any AI company, which matters here. You don't want the people grading the models to also be selling them.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it actually test?
&lt;/h2&gt;

&lt;p&gt;The core idea is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fixed question bank, run repeatedly.&lt;/strong&gt; It maintains a fixed set of tasks, throws them at each model on a schedule, and logs the scores.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Same task N times.&lt;/strong&gt; Because model outputs are stochastic, it runs each task 5 times and takes the median, plus a 95% confidence interval.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Four suites on a rotation
&lt;/h3&gt;

&lt;p&gt;It doesn't just run one kind of test — it has four suites taking turns, each watching for different things:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test Suite&lt;/th&gt;
&lt;th&gt;Frequency&lt;/th&gt;
&lt;th&gt;What it tests&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Speed (coding)&lt;/td&gt;
&lt;td&gt;Every 4 hours&lt;/td&gt;
&lt;td&gt;147 coding problems, overall coding ability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deep reasoning&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;5–7 turn multi-turn dialogues, checks long-conversation logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool calling&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;Spins up a real Docker sandbox so the AI can actually run multi-step &lt;code&gt;execute-command&lt;/code&gt; / &lt;code&gt;read-file&lt;/code&gt; / &lt;code&gt;write-file&lt;/code&gt; flows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Drift detection (canary)&lt;/td&gt;
&lt;td&gt;Hourly&lt;/td&gt;
&lt;td&gt;12 lightweight quick checks, first line of defense&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The hourly canary plays sentinel — if something starts looking off, it sounds the alarm. The daily deep reasoning and tool-calling runs are the heavier full-body checkup.&lt;/p&gt;

&lt;p&gt;The tool-calling suite is the one I find especially interesting. It actually spins up a Docker sandbox (think of it as an isolated mini-computer) and has the AI run real commands inside it, instead of just "verbally" claiming it can use tools. The results end up much closer to what you actually feel when using AI to write code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scoring isn't just right vs wrong
&lt;/h3&gt;

&lt;p&gt;A single coding task gets scored across 9 weighted dimensions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Weight&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Correctness&lt;/td&gt;
&lt;td&gt;40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexity&lt;/td&gt;
&lt;td&gt;20%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code Quality&lt;/td&gt;
&lt;td&gt;15%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stability&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Efficiency&lt;/td&gt;
&lt;td&gt;5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edge Cases&lt;/td&gt;
&lt;td&gt;3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debugging&lt;/td&gt;
&lt;td&gt;3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Format&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safety&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Correctness clearly dominates, but even if the answer runs, you'll still lose points if the code is a mess, misses edge cases, or spews garbage formatting.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it catch the moment a model starts getting dumber?
&lt;/h2&gt;

&lt;p&gt;Just having a score isn't enough — the score naturally bounces around because AI is non-deterministic. The real question is: is this drop a real regression, or just noise?&lt;/p&gt;

&lt;p&gt;This is where the project gets technically interesting. It uses an algorithm called &lt;strong&gt;CUSUM&lt;/strong&gt; — short for Cumulative Sum Control Chart. CUSUM didn't come from AI research; it's an old quality-control method from manufacturing. The idea is to keep accumulating the gap between observed performance and the baseline. Once the accumulated gap crosses a threshold, you call it: this isn't noise, something actually changed.&lt;/p&gt;

&lt;p&gt;On top of CUSUM, it also runs statistical significance testing (checking whether the difference is statistically meaningful, p-value below 0.05) as a second pass, to keep false alarms down.&lt;/p&gt;

&lt;p&gt;The real win: with this statistical machinery, a degradation can be detected &lt;strong&gt;within hours&lt;/strong&gt; of starting, rather than waiting until people are venting on social media that "AI got dumber." The system has 29 warning categories built in for different anomaly patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reading the Stupid Meter
&lt;/h2&gt;

&lt;p&gt;Each model has a live 0–100 score next to it — higher is better. Next to the score is a status tag telling you which of four states the model is in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;STABLE&lt;/strong&gt; — performing normally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VOLATILE&lt;/strong&gt; — jittering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DEGRADED&lt;/strong&gt; — already worse&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RECOVERING&lt;/strong&gt; — climbing back up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beyond the current score, it lays out each model's historical curve, so you can compare scenarios like "this model was rock-solid last week, why is it jumping around this week."&lt;/p&gt;

&lt;p&gt;In practice it feels more like a stock-trading dashboard — you're not looking at a static ranking, you're checking "right at this moment, which model is worth using." If you're still wrestling with which AI tool to pick in the first place, my earlier post &lt;a href="https://israynotarray.com/en/ai/2026/03/26/2026-ai-coding-tools-comparison/" rel="noopener noreferrer"&gt;Which AI Coding Tool Should You Pick in 2026?&lt;/a&gt; pairs well with this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Smart Router: route around degraded models automatically
&lt;/h2&gt;

&lt;p&gt;Beyond monitoring, AIStupidLevel also ships a feature called &lt;strong&gt;Smart Router&lt;/strong&gt;, which is a pretty interesting extension of the project.&lt;/p&gt;

&lt;p&gt;It's an OpenAI-compatible API endpoint, meaning code you wrote against OpenAI barely needs to change. You drop each provider's API key into it (stored with AES-256 encryption), point your base URL at it, and it routes each request to whichever model is currently in the best shape based on the live monitoring.&lt;/p&gt;

&lt;p&gt;It offers six routing strategies — just set the &lt;code&gt;model&lt;/code&gt; field in your API call to one of these and it picks dynamically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;auto-best&lt;/code&gt; — overall pick, whichever model has the best combined score right now&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;auto-coding&lt;/code&gt; — best at coding right now&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;auto-reasoning&lt;/code&gt; — strongest at reasoning&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;auto-creative&lt;/code&gt; — leans toward creative output&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;auto-cheapest&lt;/code&gt; — cheapest model above the quality bar&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;auto-fastest&lt;/code&gt; — fastest model above the quality bar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you just pass &lt;code&gt;auto&lt;/code&gt;, it uses whichever strategy you've set as your default. And if you pass a specific model name (like &lt;code&gt;claude-opus-4-7&lt;/code&gt;), it pins that model directly and skips the router. So when a model quietly starts slipping and Smart Router catches it, traffic auto-routes to a sibling that's still healthy. Pretty useful if you actually want to wire AI into a product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;So what is AIStupidLevel?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;independent, open source&lt;/strong&gt; (MIT) third-party benchmark site monitoring 21 production AI models across 7 providers (OpenAI, Anthropic, Google, xAI, DeepSeek, Kimi, GLM), 24 hours a day&lt;/li&gt;
&lt;li&gt;Method: fixed question bank, run repeatedly — each task runs 5 times, median plus 95% confidence interval, across four test suites on a rotation&lt;/li&gt;
&lt;li&gt;Uses &lt;strong&gt;CUSUM change-point detection&lt;/strong&gt; plus statistical testing to catch a model quietly degrading within hours&lt;/li&gt;
&lt;li&gt;Ships &lt;strong&gt;Smart Router&lt;/strong&gt; that auto-routes API traffic to whichever model is in the best shape based on live monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next time you feel like the AI suddenly got dumber, don't jump straight to blaming yourself — pop the dashboard open and you might actually find the evidence.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>openai</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Claude Code Auto Memory: Stop Re-Explaining Your Preferences Every Session</title>
      <dc:creator>Ray</dc:creator>
      <pubDate>Wed, 17 Jun 2026 02:50:33 +0000</pubDate>
      <link>https://dev.to/isray_notarray/claude-code-auto-memory-stop-re-explaining-your-preferences-every-session-35ne</link>
      <guid>https://dev.to/isray_notarray/claude-code-auto-memory-stop-re-explaining-your-preferences-every-session-35ne</guid>
      <description>&lt;p&gt;If you've spent any real time with Claude Code, you know this pain: you open a fresh session and it's forgotten everything you taught it yesterday. I'd tell it over and over not to dump a pile of emojis into my writing because it looks too AI — and the next morning, fresh session, emojis everywhere again.&lt;/p&gt;

&lt;p&gt;Turns out there's a fix built for exactly this, called &lt;strong&gt;Auto Memory&lt;/strong&gt;. I'd already written about &lt;a href="https://israynotarray.com/en/ai/2026/03/10/claude-md-rules-for-ai-writing-tips/" rel="noopener noreferrer"&gt;CLAUDE.md&lt;/a&gt; for setting project rules by hand, but Claude Code's memory system is bigger than just CLAUDE.md. Auto Memory quietly records your corrections and preferences as you work, so next session you don't have to say them again.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Auto Memory needs Claude Code v2.1.59 or newer. Check with &lt;code&gt;claude --version&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Auto Memory vs CLAUDE.md
&lt;/h2&gt;

&lt;p&gt;A lot of people mix these two up, so let's get it straight first.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;CLAUDE.md&lt;/th&gt;
&lt;th&gt;Auto Memory&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Who writes it&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;Claude, automatically&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What's in it&lt;/td&gt;
&lt;td&gt;Instructions and rules&lt;/td&gt;
&lt;td&gt;Learned lessons and patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;Project / user / org&lt;/td&gt;
&lt;td&gt;Per working tree&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loading&lt;/td&gt;
&lt;td&gt;Fully loaded every session&lt;/td&gt;
&lt;td&gt;First 200 lines / 25KB only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;Code conventions, workflow, architecture&lt;/td&gt;
&lt;td&gt;Build commands, debugging notes, preferences&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In short: CLAUDE.md is the set of rules you write for Claude on purpose — "use 2-space indentation," "write commit messages in English." Auto Memory is what Claude picks up on its own while working with you. You don't write it; it does.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Auto Memory actually does
&lt;/h2&gt;

&lt;p&gt;Auto Memory is basically Claude taking its own notes. When you correct it, or tell it whether an approach worked, Claude decides whether that's worth remembering for later. If it is, it saves it.&lt;/p&gt;

&lt;p&gt;So when I told it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't use so many emojis, it looks too AI&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;it saved that as a memory file, and every new session loads it back. Now it remembers I don't like emoji soup.&lt;/p&gt;

&lt;p&gt;It doesn't save everything, though — one-off discussions or things irrelevant to future work don't get written down.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it's stored (this is the confusing part)
&lt;/h2&gt;

&lt;p&gt;Here's the thing that trips everyone up. Your project has a &lt;code&gt;.claude/&lt;/code&gt; folder, but Auto Memory files are &lt;strong&gt;not&lt;/strong&gt; in there. The project &lt;code&gt;.claude/&lt;/code&gt; only holds settings (&lt;code&gt;settings.json&lt;/code&gt;, &lt;code&gt;settings.local.json&lt;/code&gt;) and rules.&lt;/p&gt;

&lt;p&gt;The actual memory lives under your home directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/Users/ray/my-project/.claude/                              &amp;lt;- project settings, inside your repo
/Users/ray/.claude/projects/-Users-ray-my-project/memory/   &amp;lt;- Auto Memory, under your home dir
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both paths contain &lt;code&gt;.claude&lt;/code&gt;, but one is in your project and one is in your home directory — don't mix them up. If you peek into your project's &lt;code&gt;.claude/&lt;/code&gt; and only find &lt;code&gt;settings.local.json&lt;/code&gt;, that's normal. The memory was never there.&lt;/p&gt;

&lt;p&gt;The memory path is derived from your git repo, so subdirectories and worktrees of the same repo share one memory. And it's machine-local — it does not sync to other machines or cloud environments.&lt;/p&gt;

&lt;p&gt;If you want it somewhere else, set &lt;code&gt;autoMemoryDirectory&lt;/code&gt; (Policy / Local / User level only — not project level, on purpose, so a shared repo can't redirect your memory somewhere shady):&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;"autoMemoryDirectory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/my-custom-memory-dir"&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;h2&gt;
  
  
  The directory structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.claude/projects/&amp;lt;project&amp;gt;/memory/
├── MEMORY.md          # index, loaded every session
├── debugging.md       # debugging notes
├── api-conventions.md # API design decisions
└── ...                # other topic files Claude creates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;MEMORY.md&lt;/code&gt; is the index — Claude uses it to track which memories exist and which file each one lives in. Only the first 200 lines / 25KB of &lt;code&gt;MEMORY.md&lt;/code&gt; loads at session start, so Claude keeps it lean and pushes detail into separate topic files. Those topic files aren't loaded on startup; Claude reads them on demand. So your memory can grow without bloating context every single time.&lt;/p&gt;

&lt;p&gt;(That 200-line cap is only for &lt;code&gt;MEMORY.md&lt;/code&gt;. CLAUDE.md always loads in full — though shorter still means better adherence.)&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you know it's writing memory?
&lt;/h2&gt;

&lt;p&gt;When you see "Writing memory" or "Recalled memory" in the Claude Code UI, that's it updating or reading memory files. You don't have to do anything; it handles it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/memory&lt;/code&gt;&lt;/strong&gt; — the main entry point. See what's loaded, toggle Auto Memory on/off, open the memory folder, or open any file in your editor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Just ask&lt;/strong&gt; — "remember: always use pnpm, never npm" saves a memory. "forget the rule about pnpm" updates or deletes it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edit by hand&lt;/strong&gt; — they're plain Markdown files under &lt;code&gt;~/.claude/projects/&lt;/code&gt;. Add, edit, or delete whatever you want.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Turn it off&lt;/strong&gt; — toggle it in &lt;code&gt;/memory&lt;/code&gt;, set &lt;code&gt;"autoMemoryEnabled": false&lt;/code&gt;, or set &lt;code&gt;CLAUDE_CODE_DISABLE_AUTO_MEMORY=1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And in case you were wondering: &lt;code&gt;/compact&lt;/code&gt; does not wipe it. The files are on disk, not in the conversation. Compacting only squeezes the chat history; &lt;code&gt;MEMORY.md&lt;/code&gt; and CLAUDE.md get re-read from disk and injected back afterward.&lt;/p&gt;

&lt;p&gt;That's the whole thing. It's a small feature, but once you stop repeating yourself every session it's hard to go back.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>productivity</category>
      <category>devtools</category>
    </item>
  </channel>
</rss>
