<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>kalizi.dev</title>
    <subtitle>Andrea Bondì (kalizi): Lead Software Engineer and Technical Advisor based in Rome, from Palermo. Ten years across ecommerce, web apps, and AI systems.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://kalizi.dev/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://kalizi.dev"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-06-21T00:00:00+00:00</updated>
    <id>https://kalizi.dev/atom.xml</id>
    <entry xml:lang="en">
        <title>On Being Agent Ready</title>
        <published>2026-06-21T00:00:00+00:00</published>
        <updated>2026-06-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/on-being-agent-ready/"/>
        <id>https://kalizi.dev/blog/on-being-agent-ready/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/on-being-agent-ready/">&lt;p&gt;I recently found out about &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;isitagentready.com&#x2F;&quot;&gt;Is Your Site Agent Ready&lt;&#x2F;a&gt;, a website by CloudFlare that tells you how much your website is indeed... agent ready.&lt;&#x2F;p&gt;
&lt;p&gt;&quot;How cool is that?&quot; I thought. Then something kicked in. I use LLMs and agents daily and they can indeed read HTML so I decided to go down the rabbit hole to have a better understanding about what being agent ready really means. For them at least.&lt;&#x2F;p&gt;
&lt;p&gt;I look up at the homepage, easy to read &quot;What do we check?&quot;, &quot;What&#x27;s the easiest way to improve my score?&quot; and &quot;Where can I learn more?&quot;. There&#x27;s plenty of stuff BUT my eyes drift to a small text at the bottom &lt;strong&gt;&quot;These are AI-generated recommendations. AI can make mistakes. Please use your professional judgment when implementing these tips...&quot;&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Just as a recap: this is an AI website to check if your website is &quot;AI ready&quot; and since it&#x27;s AI-generated you shouldn&#x27;t fully trust it? Oh dear, I love AI but what about some HI (&lt;strong&gt;Human Intelligence&lt;&#x2F;strong&gt;) more?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;baseline&quot;&gt;Baseline&lt;&#x2F;h2&gt;
&lt;p&gt;But as a SW engineer I can&#x27;t stop there, I should know more, I should measure, I should set up an experiment to have a better understanding and get to appropriate conclusions.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll be doing the whole experiment using obviously this website: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;kalizi.dev&quot;&gt;Kalizi.dev&lt;&#x2F;a&gt;. It&#x27;s behind CloudFlare so they already have it: archived, copied, stored, cached, versioned. They know it, they&#x27;ve seen each version of it. And they obviously know if any agent read it over time. Spoiler: Google, Amazon, Anthropic, OpenAI, Microsoft, ByteDance and Huawei did. I&#x27;m flattered. Next time I&#x27;d like a coffee at least.&lt;&#x2F;p&gt;









&lt;picture class=&quot;blog-picture&quot;&gt;
  &lt;source
    type=&quot;image&#x2F;avif&quot;
    srcset=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;baseline.e1bafba66c27e547.avif 480w, https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;baseline.ebd3d633e147d42d.avif 960w&quot;
    sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
  &gt;
  &lt;source
    type=&quot;image&#x2F;webp&quot;
    srcset=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;baseline.e36e54dafa995805.webp 480w, https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;baseline.5ee7b9834f805c30.webp 960w&quot;
    sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
  &gt;
  &lt;img
    src=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;baseline.43af547392dadf55.jpg&quot;
    width=&quot;960&quot;
    height=&quot;772&quot;
    alt=&quot;Baseline evaluation if kalizi.dev on being agent ready. Score 21&amp;#x2F;100&quot;
    loading=&quot;lazy&quot;
    decoding=&quot;async&quot;
  &gt;
&lt;&#x2F;picture&gt;
&lt;p&gt;Anyway, I got a baseline evaluation of 21 out of 100: they say it&#x27;s &quot;Basic Web Presence&quot; (Level 1).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;basic-web-presence&quot;&gt;Basic Web Presence&lt;&#x2F;h2&gt;
&lt;p&gt;The score is weighted on 5 sections:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Discoverability&lt;&#x2F;strong&gt;: 50 (2 out of 4)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Content&lt;&#x2F;strong&gt;: 0 (0 out of 1)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Bot Access Control&lt;&#x2F;strong&gt;: 50 (1 out of 2)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;API, Auth, MCP &amp;amp; Skill Discovery&lt;&#x2F;strong&gt;: 0 (0 out of 7)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Commerce&lt;&#x2F;strong&gt;: not checked (this isn&#x27;t an ecommerce website)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;But there was still an idea spinning in my mind. Let&#x27;s stop a moment and think what an AI agent is. Right now, when someone talks about an AI Agent it usually refers to empowering an LLM the capabilities to perform jobs and use tools inside a loop.&lt;&#x2F;p&gt;
&lt;p&gt;If we destructure an agent to its basic components, we have a series of messages and tools wrapped in a loop that goes on until the LLM chooses it&#x27;s done. Something like this if you wanna put it technical:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;messages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;    {&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;role&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;user&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;content&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt; input&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;()}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;task_complete&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #FAB387;&quot;&gt; False&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;while not&lt;&#x2F;span&gt;&lt;span&gt; task_complete&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;&quot;&gt; llm&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;messages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    task_complete&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;task_complete&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt; response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;should_call_tool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        tool_result&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;&quot;&gt; call_tool&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt;            name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tool_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #EBA0AC;font-style: italic;&quot;&gt;            args&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;tool_args&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;        )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        messages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;({&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;            &amp;quot;role&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;assistant&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;            &amp;quot;content&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;reasoning_or_request&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;        })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        messages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;({&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;            &amp;quot;role&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;tool&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;            &amp;quot;content&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; tool_result&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;        })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #CBA6F7;&quot;&gt;    else&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; response&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;output&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        messages&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;&quot;&gt;append&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;({&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;            &amp;quot;role&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt; &amp;quot;assistant&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;            &amp;quot;content&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span&gt; output&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;        })&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #FAB387;font-style: italic;&quot;&gt;print&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span&gt;output&lt;&#x2F;span&gt;&lt;span style=&quot;color: #9399B2;&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Meaning the core is STILL the LLM.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;can-an-llm-read-this-website&quot;&gt;Can an LLM read this website?&lt;&#x2F;h2&gt;
&lt;p&gt;Most of the frontier LLMs are already agents, meaning they don&#x27;t just give you an answer but they can use tools and perform tasks on your behalf. So I asked them, using the same prompt if they can read this website.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;chatgpt&quot;&gt;ChatGPT&lt;&#x2F;h3&gt;









&lt;picture class=&quot;blog-picture&quot;&gt;
  &lt;source
    type=&quot;image&#x2F;avif&quot;
    srcset=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;chatgpt.4fdc4d85a7936e2f.avif 480w, https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;chatgpt.d7428e4dd6b4f07e.avif 960w&quot;
    sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
  &gt;
  &lt;source
    type=&quot;image&#x2F;webp&quot;
    srcset=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;chatgpt.0e0b9e2fbdf91d10.webp 480w, https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;chatgpt.22ce8d77bd342af0.webp 960w&quot;
    sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
  &gt;
  &lt;img
    src=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;chatgpt.d3affd8693d9677b.jpg&quot;
    width=&quot;960&quot;
    height=&quot;962&quot;
    alt=&quot;Screenshot of ChatGPT parsing content of Kalizi.dev&quot;
    loading=&quot;lazy&quot;
    decoding=&quot;async&quot;
  &gt;
&lt;&#x2F;picture&gt;
&lt;p&gt;It seems ChatGPT can read it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;claude&quot;&gt;Claude&lt;&#x2F;h3&gt;









&lt;picture class=&quot;blog-picture&quot;&gt;
  &lt;source
    type=&quot;image&#x2F;avif&quot;
    srcset=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;claude.ac88e1764b78838c.avif 480w, https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;claude.6e772fde166e8c59.avif 960w&quot;
    sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
  &gt;
  &lt;source
    type=&quot;image&#x2F;webp&quot;
    srcset=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;claude.332f97c9a107e1f7.webp 480w, https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;claude.8a9ae3a5f37ed40c.webp 960w&quot;
    sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
  &gt;
  &lt;img
    src=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;claude.35314ac3303326f4.jpg&quot;
    width=&quot;960&quot;
    height=&quot;672&quot;
    alt=&quot;Screenshot of Claude parsing content of Kalizi.dev&quot;
    loading=&quot;lazy&quot;
    decoding=&quot;async&quot;
  &gt;
&lt;&#x2F;picture&gt;
&lt;p&gt;Claude can too.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gemini&quot;&gt;Gemini&lt;&#x2F;h3&gt;









&lt;picture class=&quot;blog-picture&quot;&gt;
  &lt;source
    type=&quot;image&#x2F;avif&quot;
    srcset=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;gemini.9c188cdfc567570b.avif 480w, https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;gemini.de28ecb82cedefaf.avif 960w&quot;
    sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
  &gt;
  &lt;source
    type=&quot;image&#x2F;webp&quot;
    srcset=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;gemini.2ab71fec9c9c292b.webp 480w, https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;gemini.a0152339747a7adf.webp 960w&quot;
    sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
  &gt;
  &lt;img
    src=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;gemini.95eddc42ec07ae64.jpg&quot;
    width=&quot;960&quot;
    height=&quot;542&quot;
    alt=&quot;Screenshot of Gemini parsing content of Kalizi.dev&quot;
    loading=&quot;lazy&quot;
    decoding=&quot;async&quot;
  &gt;
&lt;&#x2F;picture&gt;
&lt;p&gt;Gemini does it too.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s try something less &quot;corporate&quot;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;deepseek&quot;&gt;Deepseek&lt;&#x2F;h3&gt;









&lt;picture class=&quot;blog-picture&quot;&gt;
  &lt;source
    type=&quot;image&#x2F;avif&quot;
    srcset=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;deepseek.5904d39260e56e36.avif 480w, https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;deepseek.4f0794df298df97f.avif 960w&quot;
    sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
  &gt;
  &lt;source
    type=&quot;image&#x2F;webp&quot;
    srcset=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;deepseek.21016756fe482a7b.webp 480w, https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;deepseek.76fb32bf529443a0.webp 960w&quot;
    sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
  &gt;
  &lt;img
    src=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;deepseek.1fb92d47f34588c6.jpg&quot;
    width=&quot;960&quot;
    height=&quot;683&quot;
    alt=&quot;Screenshot of Deepseek parsing content of Kalizi.dev&quot;
    loading=&quot;lazy&quot;
    decoding=&quot;async&quot;
  &gt;
&lt;&#x2F;picture&gt;
&lt;p&gt;Deepseek appears to be reading the content too.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;mistral&quot;&gt;Mistral&lt;&#x2F;h3&gt;









&lt;picture class=&quot;blog-picture&quot;&gt;
  &lt;source
    type=&quot;image&#x2F;avif&quot;
    srcset=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;mistral.9d94bbcacd775c48.avif 480w, https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;mistral.a05ea5e1a4b6f355.avif 960w&quot;
    sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
  &gt;
  &lt;source
    type=&quot;image&#x2F;webp&quot;
    srcset=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;mistral.fd6afee9c330457b.webp 480w, https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;mistral.b0cf495175804562.webp 960w&quot;
    sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
  &gt;
  &lt;img
    src=&quot;https:&amp;#x2F;&amp;#x2F;kalizi.dev&amp;#x2F;processed_images&amp;#x2F;mistral.136afc999da57d14.jpg&quot;
    width=&quot;960&quot;
    height=&quot;504&quot;
    alt=&quot;Screenshot of Mistral parsing content of Kalizi.dev&quot;
    loading=&quot;lazy&quot;
    decoding=&quot;async&quot;
  &gt;
&lt;&#x2F;picture&gt;
&lt;p&gt;Even Mistral read this.&lt;&#x2F;p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;· · ·&lt;&#x2F;p&gt;
&lt;p&gt;Every single one of them.&lt;&#x2F;p&gt;
&lt;p&gt;So five different LLMs, from the big corporate ones to the scrappier open-source alternatives, all read and understood this website. Zero special configuration. No headers, no markdown negotiation, no DNS records. Just HTML.&lt;&#x2F;p&gt;
&lt;p&gt;Which raises the obvious question: if agents can already read the site just fine, what exactly was I scoring 21 out of 100 on?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;so-what-do-those-scores-mean&quot;&gt;So what do those scores mean?&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s unpack them.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;discoverability&quot;&gt;Discoverability&lt;&#x2F;h3&gt;
&lt;p&gt;This score has 4 checks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;robots.txt&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Sitemap&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;Link headers&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;DNS for AI Discovery (DNS-AID)&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;code&gt;robots.txt&lt;&#x2F;code&gt; stated goal is: &lt;em&gt;Publish &#x2F;robots.txt with clear crawl rules&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;User-agent: *&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Disallow:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Allow: &#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Sitemap: https:&#x2F;&#x2F;kalizi.dev&#x2F;sitemap.xml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I see literally nothing specific for agents.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Publish a sitemap and reference it from robots.txt&lt;&#x2F;em&gt;. Again, nothing you wouldn&#x27;t do normally.&lt;&#x2F;p&gt;
&lt;p&gt;Link Headers is the first this website isn&#x27;t ready. &lt;strong&gt;Goal: Include Link response headers for agent discovery (&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;info&#x2F;rfc8288&#x2F;&quot;&gt;RFC 8288&lt;&#x2F;a&gt;)&lt;&#x2F;strong&gt;. The RFC is 48 printable pages long, it has 7 chapters and 3 appendixes. In short it states that when your server sends a page, it should include one or more &lt;code&gt;Link: ...&lt;&#x2F;code&gt; HTTP header that tell AI agents, or other software where to find machine-readable resources about your site or API.&lt;&#x2F;p&gt;
&lt;p&gt;So server should send something like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Link: &amp;lt;&#x2F;me&amp;gt;; rel=&amp;quot;author&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Link: &amp;lt;&#x2F;projects&amp;gt;; rel=&amp;quot;collection&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Link: &amp;lt;&#x2F;blog&amp;gt;; rel=&amp;quot;collection&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Later on, HTML standard included their way to do it so there should also be something like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;html&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;&quot;&gt;link&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt; rel&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;me&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt; href&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;github.com&#x2F;kalizi&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #89B4FA;&quot;&gt;link&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt; rel&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;me&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #F9E2AF;&quot;&gt; href&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: #A6E3A1;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;kalizi-dev&#x2F;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #94E2D5;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now let&#x27;s take a look at DNS-AID before telling more. &lt;strong&gt;Goal: Publish DNS for AI Discovery (DNS-AID) records for DNS-based agent discovery&lt;&#x2F;strong&gt;. They refers &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.rfc-editor.org&#x2F;rfc&#x2F;rfc9460&quot;&gt;RFC 9460&lt;&#x2F;a&gt;. Another 48 pages.&lt;&#x2F;p&gt;
&lt;p&gt;This time it tells to add a new &lt;code&gt;SVCB&lt;&#x2F;code&gt; DNS Record to give browsers extra instructions so website loads faster. You can tell:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;use this subdomain&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;example.com. HTTPS 0 svc.example.net.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;use this non-standard port&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;example.com. HTTPS 1 . port=8443&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;check this IP addresses&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;example.com. HTTPS 1 . ipv4hint=192.0.2.10 ipv6hint=2001:db8::10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So...&lt;&#x2F;p&gt;
&lt;p&gt;Since the website is behind Cloudflare I can use nothing on the &lt;code&gt;SVCB&lt;&#x2F;code&gt; since I risk breaking cloudflare config about caching or HTTPs or leaking the IP (not that it really matters, it can be leaked many other ways but why use the proxy if I should hint the IP?). And do we really need links? I mean it may be faster for some software but is it for an agent? Agents and LLMs are meant to be smart, they &lt;em&gt;know&lt;&#x2F;em&gt; what they&#x27;re seeking for and they may also skip the links.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;content&quot;&gt;Content&lt;&#x2F;h3&gt;
&lt;p&gt;There&#x27;s only 1 key point here: Markdown Negotiation. &lt;strong&gt;Goal: Return HTML responses as markdown when agents request it&lt;&#x2F;strong&gt;. This comes directly from &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developers.cloudflare.com&#x2F;fundamentals&#x2F;reference&#x2F;markdown-for-agents&#x2F;&quot;&gt;Cloudflare docs&lt;&#x2F;a&gt; and NOT from an RFC.&lt;&#x2F;p&gt;
&lt;p&gt;This point is someway controversial since it&#x27;s just a proposal, there&#x27;s no specific evidence about &lt;code&gt;Accept: text&#x2F;markdown&lt;&#x2F;code&gt; is used by any agent, except from Cloudflare &lt;em&gt;observations&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Even OpenCode has an &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;anomalyco&#x2F;opencode&#x2F;issues&#x2F;13486&quot;&gt;open issue&lt;&#x2F;a&gt; about this but this isn&#x27;t implemented yet.&lt;&#x2F;p&gt;
&lt;p&gt;Markdown is a great format, very useful and I use it a lot with agents and even if it may help the LLMs, they may focus on the HTML to check other stuff like hidden elements, links and embedded data like JSON payloads and stuff.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;bot-access-control&quot;&gt;Bot Access Control&lt;&#x2F;h3&gt;
&lt;p&gt;Here we have &quot;Bot Access Control&quot;. &lt;strong&gt;Goal: Add User-agent rules for AI crawlers like GPTBot, Claude-Web, and others&lt;&#x2F;strong&gt;. The fun part is reading the result &lt;strong&gt;No AI-specific bot rules; wildcard rules apply to all crawlers including AI bots&lt;&#x2F;strong&gt;. Okay!&lt;&#x2F;p&gt;
&lt;p&gt;Next is &quot;Web Bot Auth request signing&quot;. I host no bots. Skip.&lt;&#x2F;p&gt;
&lt;p&gt;Last is curious, its goal states &lt;strong&gt;Declare AI content usage preferences with Content Signals in robots.txt&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;PREFERENCES&lt;&#x2F;u&gt;&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s an example Cloudflare gives:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #CDD6F4; background-color: #1E1E2E;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Content-Signal: ai-train=no, search=yes, ai-input=no&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It&#x27;s just a preference, not an enforcing so... may I say I think it&#x27;s useless?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;api-auth-mcp-skill-discovery&quot;&gt;API, Auth, MCP &amp;amp; Skill Discovery&lt;&#x2F;h3&gt;
&lt;p&gt;We can talk a lot about this section. But shortly this website exposes no API, no authentication, no specific features so this is all useless for this specific purpose.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;agent-ready-for-what&quot;&gt;Agent Ready for What?&lt;&#x2F;h2&gt;
&lt;p&gt;Here&#x27;s the thing: all those LLMs read this website just fine. No special headers, no markdown negotiation, no DNS-AID records. They parsed the HTML, understood the content, answered questions about it.&lt;&#x2F;p&gt;
&lt;p&gt;So why the 21&#x2F;100?&lt;&#x2F;p&gt;
&lt;p&gt;Because &quot;agent ready&quot; isn&#x27;t really about readability. It&#x27;s about &lt;strong&gt;actionability&lt;&#x2F;strong&gt;. There&#x27;s a difference and it matters.&lt;&#x2F;p&gt;
&lt;p&gt;An LLM reading your website is a passive operation: fetch, parse, understand. Modern LLMs are very good at this. Readable HTML is enough for that.&lt;&#x2F;p&gt;
&lt;p&gt;&quot;Agent ready&quot; in Cloudflare&#x27;s framing means something else entirely: &lt;strong&gt;can an AI agent do things on your website?&lt;&#x2F;strong&gt; Can it authenticate, call an API, invoke a skill, place an order? That&#x27;s a completely different question.&lt;&#x2F;p&gt;
&lt;p&gt;For a blog like this one, the answer is: there&#x27;s nothing to do. There are no actions to take. An agent can read about my projects but it can&#x27;t fork one, book a call, or buy anything. That&#x27;s not a failure, that&#x27;s just what this website is.&lt;&#x2F;p&gt;
&lt;p&gt;The score of 21&#x2F;100 isn&#x27;t saying my site is invisible to agents. It&#x27;s saying my site exposes no machine-actionable surface. Which is accurate.&lt;&#x2F;p&gt;
&lt;p&gt;So the real question isn&#x27;t &quot;is your site agent ready?&quot; but &lt;strong&gt;&quot;what do you want agents to actually do on your site?&quot;&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;If the answer is &quot;just read it&quot;: you&#x27;re already there. Every LLM I tested did it without any special setup.&lt;&#x2F;p&gt;
&lt;p&gt;If you want agents to interact, transact, or integrate: yes, you have work to do. APIs, auth flows, MCP endpoints, the whole stack.&lt;&#x2F;p&gt;
&lt;p&gt;For most personal blogs and informational websites, this whole framework is solving a problem that doesn&#x27;t exist yet. The LLMs can read your HTML. They&#x27;ve been doing it for years.&lt;&#x2F;p&gt;
&lt;p&gt;What Cloudflare is actually measuring is closer to &lt;strong&gt;API maturity for autonomous systems&lt;&#x2F;strong&gt;: a legitimate concern for e-commerce, SaaS platforms, service APIs. For a blog? It&#x27;s a hammer looking for a nail.&lt;&#x2F;p&gt;
&lt;p&gt;21&#x2F;100. Fine with it.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I attacked a ModernBERT with a genetic algorithm. It worked.</title>
        <published>2026-04-27T00:00:00+00:00</published>
        <updated>2026-04-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/adversarial-nlp-genetic-algorithm/"/>
        <id>https://kalizi.dev/blog/adversarial-nlp-genetic-algorithm/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/adversarial-nlp-genetic-algorithm/">&lt;p&gt;Every hacker, at some level, is someone who decided not to take &quot;secure&quot; at face value.&lt;&#x2F;p&gt;
&lt;p&gt;Kevin Mitnick broke into the FBI&#x27;s own systems while they were trying to catch him, then left a package on-site that said &quot;FBI Donuts.&quot; Frank Abagnale fooled an entire airline&#x27;s identity verification at 16. Every system has blind spots. Blind spots are where adversaries live.&lt;&#x2F;p&gt;
&lt;p&gt;For my Master&#x27;s thesis at the University of Palermo, I decided to be the adversary. Not for a financial institution or a government network. For a state-of-the-art NLP model: a fine-tuned ModernBERT on the IMDB movie reviews dataset.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The result: 100% attack success rate. An average of 18 queries to the model. Zero semantic degradation.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s how it works.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-crack-in-robust-nlp&quot;&gt;The crack in &quot;robust&quot; NLP&lt;&#x2F;h2&gt;
&lt;p&gt;Modern language models are genuinely impressive. ModernBERT achieves 93.9% accuracy on IMDB sentiment classification after a 3-epoch fine-tuning. That sounds robust. It isn&#x27;t.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s a structural vulnerability that adversarial ML research has been exploiting for years: &lt;strong&gt;models learn patterns from training data, not meaning&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Here&#x27;s a simple illustration. Take a 10-word text where every word has at least 2 synonyms. Synonyms are semantically equivalent. You can substitute them freely without changing what the sentence means. That gives you 3^10 - 1 = 59,048 semantically equivalent versions of the original text. The model was trained on a large corpus. Almost certainly not on all 59,048 variants.&lt;&#x2F;p&gt;
&lt;p&gt;Some words are frequent enough to be well-represented. Their synonyms may not be. A word and its synonym can land in completely different regions of the model&#x27;s internal representation. Even though they mean the same thing.&lt;&#x2F;p&gt;
&lt;p&gt;This is the core issue: &lt;strong&gt;semantic equivalence doesn&#x27;t guarantee classifier equivalence&lt;&#x2F;strong&gt;. The question is how you find the right substitution efficiently, automatically, and without turning the text into something nobody would actually write.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;evolution-as-an-attack-strategy&quot;&gt;Evolution as an attack strategy&lt;&#x2F;h2&gt;
&lt;p&gt;This is where genetic algorithms come in.&lt;&#x2F;p&gt;
&lt;p&gt;Genetic algorithms are search methods inspired by biological evolution. You maintain a &lt;strong&gt;population&lt;&#x2F;strong&gt; of candidate solutions (called chromosomes), evaluate each against a &lt;strong&gt;fitness function&lt;&#x2F;strong&gt;, then iterate through two operations:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mutation&lt;&#x2F;strong&gt;: small random changes to a candidate&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Crossover&lt;&#x2F;strong&gt;: combining characteristics of two parent candidates&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Over generations, the population converges toward better solutions. In this case, texts that preserve meaning but flip the model&#x27;s classification from positive to negative (or vice versa).&lt;&#x2F;p&gt;
&lt;p&gt;The core of my implementation operates on &lt;strong&gt;bigrams&lt;&#x2F;strong&gt;: pairs of adjacent words, not individual tokens. This is a deliberate choice. Bigrams explore the search space faster than single-token substitutions and better reflect how language actually shifts: context changes in chunks, not in isolated words.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-hard-constraint-semantic-honesty&quot;&gt;The hard constraint: semantic honesty&lt;&#x2F;h2&gt;
&lt;p&gt;Any adversarial example that changes the meaning of the original text isn&#x27;t demonstrating a model vulnerability. It&#x27;s just generating noise. The attack only means something if the perturbation is genuinely semantically equivalent.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Frozen vocabulary.&lt;&#x2F;strong&gt; Not everything is eligible for substitution. Proper nouns, numbers, punctuation, and unrecognized tokens are locked. The attack only operates on content words that can actually be replaced without altering what the text says.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Syntactic and morphological consistency.&lt;&#x2F;strong&gt; Every candidate substitution goes through POS-tagging via spaCy. If the original word is a plural noun, the replacement must be too. If it&#x27;s a verb in the third person singular present, the synonym gets inflected to match, using pyinflect on top of spaCy&#x27;s morphological analysis. This is where naive synonym-replacement approaches collapse: they ignore that &quot;play&quot; and &quot;plays&quot; are syntactically distinct even though they&#x27;re the same verb.&lt;&#x2F;p&gt;
&lt;p&gt;Synonyms are sourced from &lt;strong&gt;WordNet&lt;&#x2F;strong&gt;: not just a list, but a graph of semantic relationships with typed edges (hypernymy, hyponymy, antonymy, entailment). This matters because proximity in embedding space doesn&#x27;t mean semantic similarity. Word2Vec is famous for putting antonyms near each other. WordNet doesn&#x27;t have that problem.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Semantic similarity checking.&lt;&#x2F;strong&gt; After each mutation, a &lt;code&gt;paraphrase-MiniLM-L6-v2&lt;&#x2F;code&gt; model measures cosine similarity between the original and perturbed text. Drop below the configured threshold: perturbation rejected. This catches the subtle drift that accumulates when you substitute multiple words. Individually valid synonyms can compound into something semantically wrong. The model was specifically trained on paraphrase pairs, which makes it particularly well-suited for this task.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Hierarchical sentence targeting.&lt;&#x2F;strong&gt; For multi-sentence inputs, the attack doesn&#x27;t spray modifications across the whole document. It scores each sentence by its individual contribution to the classification probability, then concentrates mutations on the most impactful sentence first. This is key to the efficiency numbers.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-results&quot;&gt;The results&lt;&#x2F;h2&gt;
&lt;p&gt;I benchmarked against 9 state-of-the-art methods from the TextAttack framework: BAE, Checklist, DeepWordBug, Faster Alzantot, Input Reduction, Pruthi, PWWS, TextBugger, and TextFooler.&lt;&#x2F;p&gt;
&lt;p&gt;The composite &lt;strong&gt;Global Score&lt;&#x2F;strong&gt; weights attack success rate (40%), query efficiency (20%), and semantic preservation (40%).&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Attack&lt;&#x2F;th&gt;&lt;th&gt;Global Score&lt;&#x2F;th&gt;&lt;th&gt;Success Rate&lt;&#x2F;th&gt;&lt;th&gt;Avg. Queries&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;custom (this work)&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;97.2&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;100%&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;td&gt;&lt;strong&gt;17.9&lt;&#x2F;strong&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Pruthi&lt;&#x2F;td&gt;&lt;td&gt;89.8&lt;&#x2F;td&gt;&lt;td&gt;89.4%&lt;&#x2F;td&gt;&lt;td&gt;3,242&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Checklist&lt;&#x2F;td&gt;&lt;td&gt;86.9&lt;&#x2F;td&gt;&lt;td&gt;93.8%&lt;&#x2F;td&gt;&lt;td&gt;260&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;BAE&lt;&#x2F;td&gt;&lt;td&gt;66.2&lt;&#x2F;td&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;td&gt;324&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Faster Alzantot&lt;&#x2F;td&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;td&gt;-&lt;&#x2F;td&gt;&lt;td&gt;10,677&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;The efficiency gap is the number that matters most. Faster Alzantot is also a genetic algorithm. It needed 10,677 queries on average. This implementation needed 18. The difference comes from three things: hierarchical sentence selection, random bigram sampling instead of scoring every candidate, and early stopping the moment the label flips.&lt;&#x2F;p&gt;
&lt;p&gt;The 100% success rate against a 93.9%-accurate model is significant. Most pre-ModernBERT attacks already showed high failure rates against it. ModernBERT&#x27;s larger context window (8192 tokens vs. BERT&#x27;s 512) and improved architecture genuinely improved robustness. It held up against most of the competition. It didn&#x27;t hold up against this.&lt;&#x2F;p&gt;
&lt;p&gt;Everything runs on consumer hardware: Ryzen 9 5900x, RTX 3080, 128GB RAM. No datacenter, no API credits, no special access.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-this-actually-reveals&quot;&gt;What this actually reveals&lt;&#x2F;h2&gt;
&lt;p&gt;The obvious reading: even state-of-the-art models have exploitable blind spots. That&#x27;s true, and it&#x27;s not trivial.&lt;&#x2F;p&gt;
&lt;p&gt;The deeper reading: when a text and its semantically equivalent adversarial version receive different classifications, the model is responding to surface-level word distributions learned from training data. Not to meaning. The semantic content is the same. The prediction is not.&lt;&#x2F;p&gt;
&lt;p&gt;This is a structural property, not a bug. And it has direct consequences for any production NLP deployment where an adversary has an incentive to flip a classification:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Sentiment monitoring for market or political intelligence&lt;&#x2F;li&gt;
&lt;li&gt;Content moderation systems&lt;&#x2F;li&gt;
&lt;li&gt;Medical or legal text classification&lt;&#x2F;li&gt;
&lt;li&gt;Recommendation systems that rely on automated text quality assessment&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The attack works in &lt;strong&gt;black-box mode&lt;&#x2F;strong&gt;: no access to weights, no gradients, just query access. An API endpoint is enough. The adversary doesn&#x27;t need to know anything about the model internals.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;open-problems&quot;&gt;Open problems&lt;&#x2F;h2&gt;
&lt;p&gt;Two directions worth exploring.&lt;&#x2F;p&gt;
&lt;p&gt;Narrow domains first. A model trained exclusively on legal or medical text is probably more fragile, not less. The vocabulary is smaller, the patterns more predictable, the adversarial search space more constrained. The attack would likely need even fewer queries.&lt;&#x2F;p&gt;
&lt;p&gt;LLMs are the harder problem. The adversarial ML literature is increasingly focused there: jailbreaks, prompt injection, sleeper agents that activate only under specific trigger conditions. The evolutionary search approach generalizes in principle. The practical challenge is query cost and the stochastic nature of LLM output, which makes fitness evaluation inconsistent. Worth exploring.&lt;&#x2F;p&gt;
&lt;p&gt;Defenses are the open question. The obvious response is adversarial training: include adversarial examples in the training set. But adversarial training on one attack method doesn&#x27;t generalize well to others, and the attack evolves. The arms race is ongoing.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Bruce Schneier put it well: &lt;em&gt;&quot;If you think technology can solve your security problems, then you don&#x27;t understand the problems and you don&#x27;t understand the technology.&quot;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A 93.9%-accurate model is genuinely good. It&#x27;s also a system with structural vulnerabilities that can be located and exploited without any access to its internals. Understanding those vulnerabilities is the prerequisite for building systems that are actually reliable. Not just accurate on the test set.&lt;&#x2F;p&gt;
&lt;p&gt;The adversary always knows exactly where to look. Building the defense requires understanding the attack first.&lt;&#x2F;p&gt;
&lt;p&gt;I built the attack. The defense is the open problem.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;&lt;em&gt;The full thesis is in Italian and available on request. The implementation runs on Python 3.9-3.11, built on spaCy, WordNet (via NLTK), HuggingFace Transformers, BitsAndBytes, and pyinflect.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Lock Your Dependencies With Docker: How This Saved My Old Project React Native Android Build</title>
        <published>2023-01-15T00:00:00+00:00</published>
        <updated>2023-01-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/docker-react-native-build/"/>
        <id>https://kalizi.dev/blog/docker-react-native-build/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/docker-react-native-build/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Laravel Package Development Part 2: Controller, Request and TDD</title>
        <published>2022-09-01T00:00:00+00:00</published>
        <updated>2022-09-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/laravel-package-development-2/"/>
        <id>https://kalizi.dev/blog/laravel-package-development-2/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/laravel-package-development-2/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Laravel Package Development Part 1: Projecting a User Session Recording Package</title>
        <published>2022-08-01T00:00:00+00:00</published>
        <updated>2022-08-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/laravel-package-development-1/"/>
        <id>https://kalizi.dev/blog/laravel-package-development-1/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/laravel-package-development-1/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Laravel Data-Driven Strategies #5: email tracking, did they read your emails?</title>
        <published>2022-07-01T00:00:00+00:00</published>
        <updated>2022-07-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/laravel-email-tracking/"/>
        <id>https://kalizi.dev/blog/laravel-email-tracking/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/laravel-email-tracking/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Laravel Data-Driven Strategies #4: user navigation tracking and funnel</title>
        <published>2022-06-01T00:00:00+00:00</published>
        <updated>2022-06-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/laravel-funnel-tracking/"/>
        <id>https://kalizi.dev/blog/laravel-funnel-tracking/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/laravel-funnel-tracking/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Laravel Data-Driven Strategies #3: improve your UX using heat maps and click maps</title>
        <published>2022-05-01T00:00:00+00:00</published>
        <updated>2022-05-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/laravel-heat-maps/"/>
        <id>https://kalizi.dev/blog/laravel-heat-maps/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/laravel-heat-maps/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Laravel Data-Driven Strategies #2: setup user session recording in your application</title>
        <published>2022-04-01T00:00:00+00:00</published>
        <updated>2022-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/laravel-session-recording/"/>
        <id>https://kalizi.dev/blog/laravel-session-recording/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/laravel-session-recording/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Laravel Data-Driven Strategies #1: setup A&#x2F;B testing in your application</title>
        <published>2022-03-01T00:00:00+00:00</published>
        <updated>2022-03-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/laravel-ab-testing/"/>
        <id>https://kalizi.dev/blog/laravel-ab-testing/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/laravel-ab-testing/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Defending Against Ransomware Attacks</title>
        <published>2021-09-01T00:00:00+00:00</published>
        <updated>2021-09-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/defending-ransomware/"/>
        <id>https://kalizi.dev/blog/defending-ransomware/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/defending-ransomware/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Security 101 for Java: CWE-22 Path Traversal</title>
        <published>2021-08-01T00:00:00+00:00</published>
        <updated>2021-08-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/java-security-cwe22-path-traversal/"/>
        <id>https://kalizi.dev/blog/java-security-cwe22-path-traversal/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/java-security-cwe22-path-traversal/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Combining Production and Remote Debugging in Java Applications</title>
        <published>2021-07-01T00:00:00+00:00</published>
        <updated>2021-07-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/java-remote-debugging/"/>
        <id>https://kalizi.dev/blog/java-remote-debugging/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/java-remote-debugging/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>I&#x27;m Learning Ethical Hacking, here&#x27;s how I got from 0 to 1</title>
        <published>2021-06-10T00:00:00+00:00</published>
        <updated>2021-06-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/ethical-hacking-0-to-1/"/>
        <id>https://kalizi.dev/blog/ethical-hacking-0-to-1/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/ethical-hacking-0-to-1/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Open Source Vulnerabilities in Web Development</title>
        <published>2021-05-01T00:00:00+00:00</published>
        <updated>2021-05-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/open-source-vulnerabilities-web/"/>
        <id>https://kalizi.dev/blog/open-source-vulnerabilities-web/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/open-source-vulnerabilities-web/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Best WordPress Hosting Solutions for Security in 2021</title>
        <published>2021-04-01T00:00:00+00:00</published>
        <updated>2021-04-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/wordpress-hosting-security-2021/"/>
        <id>https://kalizi.dev/blog/wordpress-hosting-security-2021/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/wordpress-hosting-security-2021/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to Start WordPress Plugin Development With Docker: Part 2, Create a Simple Page</title>
        <published>2021-03-01T00:00:00+00:00</published>
        <updated>2021-03-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/wordpress-plugin-docker-2/"/>
        <id>https://kalizi.dev/blog/wordpress-plugin-docker-2/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/wordpress-plugin-docker-2/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to Start WordPress Plugin Development With Docker: Part 1, Docker and Admin Panel</title>
        <published>2021-02-01T00:00:00+00:00</published>
        <updated>2021-02-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/wordpress-plugin-docker-1/"/>
        <id>https://kalizi.dev/blog/wordpress-plugin-docker-1/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/wordpress-plugin-docker-1/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Gatsby.js, GitHub and Cloudflare: Build a Static Website With React</title>
        <published>2020-09-01T00:00:00+00:00</published>
        <updated>2020-09-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/gatsby-github-cloudflare-static-site/"/>
        <id>https://kalizi.dev/blog/gatsby-github-cloudflare-static-site/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/gatsby-github-cloudflare-static-site/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Machine Learning With PHP Using Support Vector Machine (SVM) via ext-svm</title>
        <published>2020-06-01T00:00:00+00:00</published>
        <updated>2020-06-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/machine-learning-php-svm/"/>
        <id>https://kalizi.dev/blog/machine-learning-php-svm/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/machine-learning-php-svm/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Setup a Laravel Admin Dashboard With InfyOm in Few Minutes, Even on Existing Projects</title>
        <published>2020-03-01T00:00:00+00:00</published>
        <updated>2020-03-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/laravel-admin-dashboard-infyom/"/>
        <id>https://kalizi.dev/blog/laravel-admin-dashboard-infyom/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/laravel-admin-dashboard-infyom/"></content>
        
    </entry>
    <entry xml:lang="en">
        <title>Build JWT Authentication Between Multiple APIs With Laravel</title>
        <published>2020-01-01T00:00:00+00:00</published>
        <updated>2020-01-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Andrea Bondì
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://kalizi.dev/blog/laravel-jwt-authentication/"/>
        <id>https://kalizi.dev/blog/laravel-jwt-authentication/</id>
        
        <content type="html" xml:base="https://kalizi.dev/blog/laravel-jwt-authentication/"></content>
        
    </entry>
</feed>
