<?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: Omkar Palika</title>
    <description>The latest articles on DEV Community by Omkar Palika (@omkarpalika).</description>
    <link>https://dev.to/omkarpalika</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%2F2932181%2Fbddc0e24-e22e-4c99-a68b-c3da1e74e267.jpg</url>
      <title>DEV Community: Omkar Palika</title>
      <link>https://dev.to/omkarpalika</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/omkarpalika"/>
    <language>en</language>
    <item>
      <title>I sent an AI agent to buy from real stores. Here's what actually breaks.</title>
      <dc:creator>Omkar Palika</dc:creator>
      <pubDate>Fri, 17 Jul 2026 17:20:28 +0000</pubDate>
      <link>https://dev.to/omkarpalika/i-sent-an-ai-agent-to-buy-from-real-stores-heres-what-actually-breaks-4g92</link>
      <guid>https://dev.to/omkarpalika/i-sent-an-ai-agent-to-buy-from-real-stores-heres-what-actually-breaks-4g92</guid>
      <description>&lt;p&gt;AI agents are starting to shop for people. ChatGPT has an operator that clicks around the web. Perplexity ships a "buy" button. Anthropic and others are wiring agents into real checkout flows. If you run an online store, some fraction of your future customers won't be humans clicking — they'll be agents acting on a human's behalf.&lt;/p&gt;

&lt;p&gt;Which raised a question I couldn't answer for my own projects: &lt;strong&gt;can an AI agent actually complete a purchase on this store?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every "agent-readiness" tool I found just lints your markup — does your robots.txt allow agent crawlers, do you have structured data, that kind of thing. Useful, but it answers a &lt;em&gt;different&lt;/em&gt; question. Clean markup doesn't mean an agent can navigate your funnel any more than a valid HTML resume means you can do the job. The only way to know is to send an agent through and watch where it dies.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://github.com/OmkarPalika/agentiqa" rel="noopener noreferrer"&gt;AgentiQA&lt;/a&gt;. It's open source (MIT). Here's how it works and — more interestingly — what I found when I pointed it at real stores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two layers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Static checks&lt;/strong&gt; (stdlib only, no API key): does robots.txt allow agent user-agents (&lt;code&gt;Claude-User&lt;/code&gt;, &lt;code&gt;ChatGPT-User&lt;/code&gt;, &lt;code&gt;OAI-SearchBot&lt;/code&gt;, &lt;code&gt;PerplexityBot&lt;/code&gt;), is there JSON-LD &lt;code&gt;Product&lt;/code&gt;/&lt;code&gt;Offer&lt;/code&gt; data, OpenGraph tags, a reachable sitemap. This is the cheap "is the door unlocked" pass.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The live shopper agent&lt;/strong&gt;: Claude driving a real headless Chromium browser through the actual funnel — find a product, add to cart, reach checkout — recording milestones as it goes. This is the part that answers the real question.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the agent "sees" the page
&lt;/h2&gt;

&lt;p&gt;No screenshots, no vision model. The agent reads a &lt;strong&gt;text snapshot&lt;/strong&gt; of the DOM: the page URL and title, every interactive element indexed by a number, and the visible text. Roughly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;URL: https://store.example/
TITLE: All Products

INTERACTIVE ELEMENTS:
[0] &amp;lt;a href=/product/blue-top&amp;gt; Blue Top
[1] &amp;lt;button&amp;gt; Add to cart
[2] &amp;lt;input type=text name=search&amp;gt; Search
...

VISIBLE TEXT (truncated):
Blue Top  Rs. 500  In Stock ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent gets a tiny toolset — &lt;code&gt;read_page&lt;/code&gt;, &lt;code&gt;click(element_id)&lt;/code&gt;, &lt;code&gt;type_text(element_id, text)&lt;/code&gt;, &lt;code&gt;goto(url)&lt;/code&gt;, &lt;code&gt;record_milestone(stage)&lt;/code&gt; — and loops: read the page, decide, act, read again. Text-only is cheaper than vision, deterministic, and it's roughly what an agent shopper actually operates on anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  The safety part that matters: the payment guard is code, not a prompt
&lt;/h2&gt;

&lt;p&gt;Any tool that drives a browser through checkout has to &lt;em&gt;never&lt;/em&gt; touch payment data. You cannot rely on a system prompt for that — prompts are suggestions, and a model under pressure to "complete the task" can rationalize its way past one.&lt;/p&gt;

&lt;p&gt;So the refusal lives in the executor, not the instructions. Before any keystroke, the field is checked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;PAYMENT_FIELD_RE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;card|cvv|cvc|cc-|expir|security.?code|pan\b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IGNORECASE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_payment_field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;autocomplete&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;placeholder&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aria-label&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_attribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;PAYMENT_FIELD_RE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the agent tries to type into anything that looks like a payment field, the tool returns a hard &lt;code&gt;REFUSED&lt;/code&gt; and tells it to stop and summarize. It also never creates accounts and never submits a final order — it stops at the checkout page. The model's judgment is a second layer, not the only one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero-cost driver: the Claude CLI, not just an API key
&lt;/h2&gt;

&lt;p&gt;The obvious way to drive this is the Anthropic API, which costs ~$1–2 per full audit. But for a solo dev validating an idea, I didn't want a per-run bill. So there's a second driver that speaks to the &lt;code&gt;claude&lt;/code&gt; CLI (the Claude Code subscription) over a small JSON protocol — one action per turn, resumed across steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; agentiqa https://your-store.com &lt;span class="nt"&gt;--driver&lt;/span&gt; cli   &lt;span class="c"&gt;# subscription, no API key&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; agentiqa https://your-store.com &lt;span class="nt"&gt;--driver&lt;/span&gt; api   &lt;span class="c"&gt;# API key, faster&lt;/span&gt;
&lt;span class="c"&gt;# default: api if ANTHROPIC_API_KEY is set, else cli&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same browser loop, same safety guards — just a different way to get the model's next move. It means you can run the whole thing on a subscription you already pay for.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually found
&lt;/h2&gt;

&lt;p&gt;Here's the honest part, and it wasn't what I expected going in.&lt;/p&gt;

&lt;p&gt;I ran the benchmark against a set of real, public demo stores — the kind built to be tested against, with genuine cart and checkout flows. My assumption was that agents would faceplant everywhere. They didn't.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On clean, functional stores, the agent checked out fine.&lt;/strong&gt; Product → cart → checkout, no drama. One "failure" in my batch turned out to be a dead server throwing a Cloudflare SSL error — not an agent problem at all.&lt;/p&gt;

&lt;p&gt;The failures that &lt;em&gt;are&lt;/em&gt; real are dumber and quieter than "the agent is dumb":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;"add to cart" button that works for a human click but produces no state an agent can detect&lt;/strong&gt; — no cart-count change, no confirmation, no visible signal. A human sees the cart bump and moves on. The agent has no way to know it worked, so it retries or stalls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No cart link anywhere in the nav.&lt;/strong&gt; Humans know to look top-right. An agent needs a discoverable path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product data an agent can't parse&lt;/strong&gt; — price and availability rendered in a way that's obvious visually but not in the DOM text.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these show up in a markup linter. And here's the kicker I found: a store scored &lt;strong&gt;1/4 on static readiness&lt;/strong&gt; and the agent still checked out perfectly. Static score did &lt;strong&gt;not&lt;/strong&gt; predict agent success. The behavioral test and the markup test measure different things — you need the behavioral one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it on your store
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
playwright &lt;span class="nb"&gt;install &lt;/span&gt;chromium

&lt;span class="c"&gt;# free static check, no API key:&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; agentiqa https://your-store.com &lt;span class="nt"&gt;--no-agent&lt;/span&gt;

&lt;span class="c"&gt;# full run with the live agent:&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; agentiqa https://your-store.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get an HTML report: a verdict banner (did the agent complete checkout?), a prioritized fix list, the funnel, and the full step-by-step transcript of what the agent did. There's also a batch mode that runs a list of stores and emits an aggregate leaderboard.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Only run it against stores you own or have permission to test.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where this goes
&lt;/h2&gt;

&lt;p&gt;Agentic commerce is early. Right now the interesting finding is that the gap between "works for humans" and "works for agents" is made of small, invisible things — and nobody's funnel-testing for them yet. The tool is open source; I'd genuinely like to know what breaks on &lt;em&gt;your&lt;/em&gt; store, because my sample is small and demo stores are easier than messy production ones.&lt;/p&gt;

&lt;p&gt;Repo, demo GIF, and the full report format: &lt;strong&gt;&lt;a href="https://github.com/OmkarPalika/agentiqa" rel="noopener noreferrer"&gt;https://github.com/OmkarPalika/agentiqa&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you run an e-commerce store and want to know whether an AI agent can buy from you — or you just want to see an agent narrate its way through a checkout and give up at a broken button — point it at your site and tell me what you find.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>webdev</category>
      <category>ecommerce</category>
    </item>
  </channel>
</rss>
