{"id":725020,"date":"2026-05-01T17:42:41","date_gmt":"2026-05-01T14:42:41","guid":{"rendered":""},"modified":"2026-05-01T17:42:41","modified_gmt":"2026-05-01T14:42:41","slug":"how-to-build-seo-agent-skills-that-actually-work","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/","title":{"rendered":"How to build SEO agent skills that actually work"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_84 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a297dbe9b038\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #dd3333;color:#dd3333\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #dd3333;color:#dd3333\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a297dbe9b038\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Most_AI_SEO_%E2%80%9Cskills%E2%80%9D_are_just_prompts_Learn_the_system_behind_reliable_agents_tools_memory_templates_and_a_built-in_review_layer\" >Most AI SEO \u201cskills\u201d are just prompts. Learn the system behind reliable agents: tools, memory, templates, and a built-in review layer.<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Why_most_AI_SEO_skills_fail\" >Why most AI SEO skills fail<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Build_SEO_agent_skills_as_workspaces\" >Build SEO agent skills as workspaces<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#AGENTSmd_is_the_instruction_manual\" >AGENTS.md is the instruction manual\u00a0<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Scripts_are_the_agents_tools\" >Scripts are the agent\u2019s tools<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#References_are_the_judgment_calls\" >References are the judgment calls<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Memory_is_institutional_knowledge\" >Memory is institutional knowledge<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Templates_enforce_consistency\" >Templates enforce consistency\u00a0<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Walkthrough_Building_the_crawler_from_scratch\" >Walkthrough: Building the crawler from scratch<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Version_1_The_naive_approach\" >Version 1: The naive approach<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Version_2_Added_a_script\" >Version 2: Added a script<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Version_3_Introducing_rate_limiting_and_resume\" >Version 3: Introducing rate limiting and resume<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Version_4_JavaSript_rendering\" >Version 4: JavaSript rendering<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Version_5_Time_for_templates_and_memory\" >Version 5: Time for templates and memory<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Equip_agents_with_the_right_tools\" >Equip agents with the right tools<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Progressive_disclosure_Dont_dump_everything_at_once\" >Progressive disclosure: Don\u2019t dump everything at once<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#The_10_gotchas_Failure_modes_that_will_burn_you\" >The 10 gotchas: Failure modes that will burn you<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-18\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Agents_hallucinate_data_they_cant_verify\" >Agents hallucinate data they can\u2019t verify\u00a0<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-19\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Knowledge_doesnt_transfer_between_agents\" >Knowledge doesn\u2019t transfer between agents<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-20\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Output_format_drifts_between_runs\" >Output format drifts between runs<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-21\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Agents_confidently_report_issues_that_dont_exist\" >Agents confidently report issues that don\u2019t exist<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-22\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Bare_HTTP_requests_get_blocked_everywhere\" >Bare HTTP requests get blocked everywhere<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-23\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Dont_guess_URL_paths\" >Don\u2019t guess URL paths<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-24\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#%E2%80%98Done_vs_%E2%80%98in_review_matters\" >\u2018Done\u2019 vs. \u2018in review\u2019 matters\u00a0<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-25\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Categories_must_be_hyper-specific\" >Categories must be hyper-specific<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-26\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Never_ask_an_LLM_to_compile_data\" >Never ask an LLM to compile data<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-27\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Agents_will_try_things_you_never_planned\" >Agents will try things you never planned<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-28\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Build_the_reviewer_first\" >Build the reviewer first<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-29\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#The_validation_standard_Our_unfair_advantage\" >The validation standard (Our unfair advantage)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-30\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Sandbox_testing_Train_on_planted_bugs\" >Sandbox testing: Train on planted bugs<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-31\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Consistency_The_unsexy_secret\" >Consistency: The unsexy secret<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-32\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#The_stack_that_makes_it_work\" >The stack that makes it work<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-33\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#The_result\" >The result<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-34\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-build-seo-agent-skills-that-actually-work\/#Topics_on_this_page\" >Topics on this page<\/a><\/li><\/ul><\/li><\/ul><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h2 class=\"subhead\" itemprop=\"alternativeHeadline\"><span class=\"ez-toc-section\" id=\"Most_AI_SEO_%E2%80%9Cskills%E2%80%9D_are_just_prompts_Learn_the_system_behind_reliable_agents_tools_memory_templates_and_a_built-in_review_layer\"><\/span>Most AI SEO \u201cskills\u201d are just prompts. Learn the system behind reliable agents: tools, memory, templates, and a built-in review layer.<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p><\/p>\n<div class=\"bialty-container\">\n<p>I\u2019ve built 10+ SEO agent skills in 34 days. Six worked on the first try. The other four taught me everything I\u2019m about to show you about the folder structure most LinkedIn posts about AI SEO skills gloss over.<\/p>\n<p>What makes these agents reliable isn\u2019t better prompts. It\u2019s the architecture behind them. Here\u2019s how to build an agent from scratch, test it, fix it, and ship it with confidence.<\/p>\n<h2 id=\"why-most-ai-seo-skills-fail\" class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Why_most_AI_SEO_skills_fail\"><\/span>Why most AI SEO skills fail<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Here\u2019s what a typical \u201cAI SEO prompt\u201d looks like on LinkedIn:<\/p>\n<pre class=\"wp-block-code\"><code>You are an SEO expert. Analyze the following website and provide a comprehensive audit with recommendations.<\/code><\/pre>\n<p>That\u2019s it. One prompt. Maybe some formatting instructions. The person posts a screenshot of the output, gets 500 likes, and moves on. The output looks professional. It reads well. It\u2019s also 40% wrong.<\/p>\n<p>I know because I tried this exact <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/download-scripts-themes-apps\/\" data-internallinksmanager029f6b8e52c=\"9\" title=\"Download Scripts &amp; Themes &amp; Apps\" target=\"_blank\" rel=\"noopener\">app<\/a>roach. Early in the build, I pointed an agent at a website and said, \u201cfind SEO issues.\u201d It came back with 20 findings. Eight didn\u2019t exist. The agent had never visited some of the URLs it was reporting on.<\/p>\n<p>Three problems kill single-prompt skills:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>No tools:<\/strong> The agent has no way to actually check the website. It\u2019s working from training data and guessing. When you ask, \u201cDoes this site have canonical tags?\u201d the agent imagines what the site probably looks like rather than fetching the HTML and parsing it.<\/li>\n<li><strong>No verification:<\/strong> Nobody checks if the output is true. The agent says, \u201cmissing meta descriptions on 15 pages.\u201d Which 15? Are those pages even indexed? Are they noindexed on purpose? No one asks. No one verifies.<\/li>\n<li><strong>No memory:<\/strong> Run the same skill twice, you get different output. Different structure. Different severity labels. Sometimes different findings entirely. There\u2019s no consistency because there\u2019s no template, no schema, no record of past runs.<\/li>\n<\/ul>\n<p>If your skill is a prompt in a single file, you don\u2019t have a skill. You have a coin flip.<\/p>\n<div style=\"background: radial-gradient(circle at 30% 40%, rgba(184, 111, 255, 0.15), rgba(0, 169, 255, 0.15) 40%, #CDE8FD 70%); padding: 30px; width: 100%; max-width: 802px; color: #000000 !important; font-family: Arial, sans-serif; margin: 25px 0 30px 0; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); position: relative; box-sizing: border-box;\">\n<div style=\"width: 100%; max-width: 100%; margin-bottom: 20px; text-align: left; padding-right: 20px; box-sizing: border-box;\">\n<div id=\"semrush-one-headline\" class=\"headline-responsive\" style=\"font-family: Oswald, sans-serif; font-size: 30px; font-weight: normal; margin: 0; color: #000000 !important; line-height: 1.2;\">\n        Your customers search everywhere. Make sure your brand <span style=\"background: linear-gradient(90deg, #D56EFE 0%, #068EF8 51%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;\">shows up<\/span>.\n      <\/div>\n<p id=\"semrush-one-subhead\" style=\"font-family: Roboto, sans-serif; font-size: 18px; font-weight: 300; line-height: 25px; margin: 12px 0 0 0; color: #000000 !important;\">\n        The SEO toolkit you know, plus the AI visibility data you need.\n      <\/p>\n<\/p><\/div>\n<div style=\"margin-bottom: 15px;\">\n      <span id=\"semrush-one-cta\" style=\"display: inline-block; background-color: #FF642D; color: white; height: 44px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; padding: 0 24px; font-weight: bold; white-space: nowrap; box-sizing: border-box; text-decoration: none; line-height: 44px;\">Start Free Trial<\/span>\n    <\/div>\n<div style=\"font-size: 12px;\">\n<div style=\"font-family: Roboto, sans-serif; font-weight: 300; color: #000000; margin-bottom: 4px;\">Get started with<\/div>\n<p>      <img loading=\"lazy\" width=\"400\" height=\"52\" decoding=\"async\" http: alt=\"Semrush One Logo\" style=\"height: 16px; width: auto; display: block;\" src=\"https:\/\/searchengineland.com\/wp-content\/seloads\/2025\/11\/semrush-one.webp\"><img loading=\"lazy\" width=\"400\" height=\"52\" decoding=\"async\" src=\"https:\/\/searchengineland.com\/wp-content\/seloads\/2025\/11\/semrush-one.webp\" alt=\"Semrush One Logo\" style=\"height: 16px; width: auto; display: block;\">\n    <\/div>\n<\/p><\/div>\n<style>\n  @media (max-width: 768px) {\n    .headline-responsive {\n      font-size: 30px !important;\n      line-height: 1.3 !important;\n    }\n  }\n<\/style>\n<h2 id=\"build-seo-agent-skills-as-workspaces\" class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Build_SEO_agent_skills_as_workspaces\"><\/span>Build SEO agent skills as workspaces<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Every agent in our system has a workspace. Think of it like a new hire\u2019s desk, stocked with everything they need. Here\u2019s what the workspace looks like for the agent that crawls websites and maps their architecture:<\/p>\n<pre class=\"wp-block-code\"><code>agent-workspace\/\n  AGENTS.md          instructions, rules, output format\n  SOUL.md            personality, principles, quality bar\n  scripts\/\n    crawl_site.js    tool the agent calls to crawl\n    parse_sitemap.sh tool to read XML sitemaps\n  references\/\n    criteria.md      what counts as an issue vs noise\n    gotchas.md       known false positives to watch for\n  memory\/\n    runs.log         past execution history\n  templates\/\n    output.md        expected output structure<\/code><\/pre>\n<p>Six components. One prompt file would cover maybe 20% of this.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-agents-md-is-the-instruction-manual-nbsp\"><span class=\"ez-toc-section\" id=\"AGENTSmd_is_the_instruction_manual\"><\/span>AGENTS.md is the instruction manual\u00a0<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>I wrote thousands of words of methodology into AGENTS.md.\u00a0 Instead of \u201ccrawl the site,\u201d I laid out the steps: \u201cStart with the sitemap. If no sitemap exists, check \/sitemap.xml, \/sitemap_index.xml, and robots.txt for sitemap references.\u00a0<\/p>\n<p>Respect crawl-delay. Use a browser user-agent string, never a bare request. If you get 403s, note the pattern and try with different headers before reporting it as a block.\u201d<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-scripts-are-the-agent-s-tools\"><span class=\"ez-toc-section\" id=\"Scripts_are_the_agents_tools\"><\/span>Scripts are the agent\u2019s tools<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The agent calls node crawl_site.js \u2013url to analyze website data. It doesn\u2019t write curl commands from scratch every time. That\u2019s the difference between giving someone a toolbox and telling them to forge their own wrench.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-references-are-the-judgment-calls\"><span class=\"ez-toc-section\" id=\"References_are_the_judgment_calls\"><\/span>References are the judgment calls<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This contains criteria for what counts as an issue. Known false positives to watch for. Edge cases that took me 20 years to learn. The agent reads these when it encounters something ambiguous.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-memory-is-institutional-knowledge\"><span class=\"ez-toc-section\" id=\"Memory_is_institutional_knowledge\"><\/span>Memory is institutional knowledge<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Here I keep a log of past runs:<\/p>\n<ul class=\"wp-block-list\">\n<li>What it found last time.\u00a0<\/li>\n<li>How long the crawl took.\u00a0<\/li>\n<li>What broke.\u00a0<\/li>\n<\/ul>\n<p>The next execution benefits from the last.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-templates-enforce-consistency-nbsp\"><span class=\"ez-toc-section\" id=\"Templates_enforce_consistency\"><\/span>Templates enforce consistency\u00a0<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This is where I get specific about the output I want: \u201cUse this exact structure. These exact fields. This severity scale.\u201d Output templates are the difference between getting the same quality in run 14 as you did in run 1.<\/p>\n<h2 id=\"walkthrough-building-the-crawler-from-scratch\" class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Walkthrough_Building_the_crawler_from_scratch\"><\/span>Walkthrough: Building the crawler from scratch<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Let me show you exactly how I built the crawler. It maps a site\u2019s architecture, discovers every page, and reports what it finds.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-version-1-the-naive-approach\"><span class=\"ez-toc-section\" id=\"Version_1_The_naive_approach\"><\/span>Version 1: The naive approach<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>I provided the instruction: \u201cCrawl this website and list all pages.\u201d<\/p>\n<p>The agent wrote its own HTTP requests, used bare curl, and got blocked by the first site it touched. Every modern CDN blocks requests without a browser user-agent string, so it was dead on arrival.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-version-2-added-a-script\"><span class=\"ez-toc-section\" id=\"Version_2_Added_a_script\"><\/span>Version 2: Added a script<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>I built crawl_site.js using Playwright. This version used a headless browser and a real user-agent. The agent calls the script instead of writing its own requests.<\/p>\n<p>This worked on small sites, but it crashed on anything over 200 pages. Because there was no rate limiting and no resume capability, it hammered servers until they blocked us.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-version-3-introducing-rate-limiting-and-resume\"><span class=\"ez-toc-section\" id=\"Version_3_Introducing_rate_limiting_and_resume\"><\/span>Version 3: Introducing rate limiting and resume<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>I added throttling with a two requests per second default and never every two seconds for CDN-protected sites. The agent reads robots.txt and adjusts its speed without asking permission. I also added checkpoint files so a crashed crawl can resume from where it stopped.<\/p>\n<p>This worked on most sites, but it failed on sites that require JavaScript rendering.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-version-4-javasript-rendering\"><span class=\"ez-toc-section\" id=\"Version_4_JavaSript_rendering\"><\/span>Version 4: JavaSript rendering<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This time, I added a browser rendering mode. The agent detects whether a site is a single-page app (React, Next.js, Angular) and automatically switches to full browser rendering.<\/p>\n<p>It also compares rendered HTML against source HTML, and I found real issues this way: Sites where the source HTML was an empty shell but the rendered page was full of content. Google might or might not render it properly. Now we check both.<\/p>\n<p>This version worked on everything, but the output was inconsistent between runs.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-version-5-time-for-templates-and-memory\"><span class=\"ez-toc-section\" id=\"Version_5_Time_for_templates_and_memory\"><\/span>Version 5: Time for templates and memory<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>For this version, I added templates\/output.md with exact fields: URL count, sitemap coverage, blocked paths, response code distribution, render mode used, and issues found. This way every run produces the same structure.<\/p>\n<p>I also added memory\/runs.log. The agent appends a summary after every execution. Next time it runs, it reads the log and can compare results, like \u201cLast crawl found 485 pages. This crawl found 487. Two new pages added.\u201d<\/p>\n<p>Version 5 is what we run today. Five iterations in one day of building.<\/p>\n<pre class=\"wp-block-code\"><code>THE CRAWLER'S EVOLUTION\n\n  v1: Raw curl           \u2192 blocked everywhere\n  v2: Playwright script  \u2192 crashed on large sites\n  v3: Rate limiting      \u2192 couldn't handle JS sites\n  v4: Browser rendering  \u2192 inconsistent output\n  v5: Templates + memory \u2192 stable, consistent, reliable\n\n  Time: 1 day. Lesson: the first version never works.<\/code><\/pre>\n<p>The pattern is always the same: Start small, hit a wall, fix the wall, hit the next wall.<\/p>\n<p>Five versions in one day doesn\u2019t mean five failures. It means five lessons that are now permanently encoded. I\u2019ve rebuilt delivery systems four times over 20 years. The process doesn\u2019t change. You start with what\u2019s elegant, then reality hits, and you end up with what works.<\/p>\n<p><strong>Tip:<\/strong> Don\u2019t try to build the perfect skill on the first attempt. Build the simplest thing that could possibly work. Run it on real data and watch it fail. The failures tell you exactly what to add next. Every version of our crawler was a direct response to a specific failure. Not a feature we imagined. A problem we hit.<\/p>\n<p><!-- START INLINE FORM --><\/p>\n<p><!-- END INLINE FORM --><\/p>\n<hr class=\"wp-block-separator has-text-color has-cyan-bluish-gray-color has-css-opacity has-cyan-bluish-gray-background-color has-background\">\n<h2 id=\"equip-agents-with-the-right-tools\" class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Equip_agents_with_the_right_tools\"><\/span>Equip agents with the right tools<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This is the most important architectural decision I made.<\/p>\n<p>When you write \u201cuse curl to fetch the sitemap\u201d in your instructions, the agent generates a curl command from scratch every time. Sometimes it adds the right headers. Sometimes it doesn\u2019t. Sometimes it follows redirects. Sometimes it forgets.<\/p>\n<p>When you give the agent a script called parse_sitemap.sh, it calls the script. The script always has the right headers, always follows redirects, and always handles edge cases. The agent\u2019s judgment goes into WHEN to call the tool and WHAT to do with the results. The tool handles HOW.<\/p>\n<p>Our agents have tools for everything:<\/p>\n<ul class=\"wp-block-list\">\n<li>crawl_site.js: Playwright-based crawler with rate limiting, resume, and rendering<\/li>\n<li>parse_sitemap.sh: Fetches and parses XML sitemaps, counts URLs, detects nested indexes<\/li>\n<li>check_status.sh: Tests HTTP response codes with proper user-agent strings<\/li>\n<li>extract_links.sh: Pulls internal and external links from page HTML<\/li>\n<\/ul>\n<p>The agent decides which tools to use and what parameters to set. The crawler chooses its own crawl speed based on what it encounters.\u00a0 It reads robots.txt and adjusts. It has judgment within guardrails.<\/p>\n<p>Think of it this way: You give a new hire a CRM, not instructions on how to build a database. The tools are the CRM. The instructions are the process for using them.<\/p>\n<h2 id=\"progressive-disclosure-dont-dump-everything-at-once\" class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Progressive_disclosure_Dont_dump_everything_at_once\"><\/span>Progressive disclosure: Don\u2019t dump everything at once<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Here\u2019s a mistake I made early: I put everything in AGENTS.md. Every rule. Every edge case. Every gotcha. Thousands of words.<\/p>\n<p>The agent got confused. It had too much context and it started prioritizing obscure edge cases over common tasks. It would spend time checking for hash routing issues on a WordPress blog.<\/p>\n<p>The fix: progressive disclosure.<\/p>\n<p>Core rules that affect the 80% case go in AGENTS.md. This is what the agent needs to know for every single run.<\/p>\n<p>Edge cases go in references\/gotchas.md. The agent reads this file when it encounters something ambiguous. Not before every task. Only when it needs it.<\/p>\n<p>Criteria for severity scoring go in references\/criteria.md. The agent checks this when it finds an issue and needs to decide how bad it is. Not upfront.<\/p>\n<p>This is the same way a skilled employee operates. They know the core process by heart. They check the handbook when something weird comes up. They don\u2019t re-read the entire handbook before answering every email.<\/p>\n<p>If your agent output is inconsistent but your instructions are detailed, the problem is usually too much context. Agents, like new hires, perform better with clear priorities and a reference shelf than with a 50-page manual they have to digest before every task.<\/p>\n<h2 id=\"the-10-gotchas-failure-modes-that-will-burn-you\" class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_10_gotchas_Failure_modes_that_will_burn_you\"><\/span>The 10 gotchas: Failure modes that will burn you<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Every one of these lessons cost me hours. They\u2019re now encoded in our agents\u2019 references\/gotchas.md files so they can\u2019t happen again.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-agents-hallucinate-data-they-can-t-verify-nbsp\"><span class=\"ez-toc-section\" id=\"Agents_hallucinate_data_they_cant_verify\"><\/span>Agents hallucinate data they can\u2019t verify\u00a0<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>I asked the research agent to find law firms and count their attorneys. It made every number up. It had never visited any of their websites.<\/p>\n<p>Only ask agents to produce data they can actually fetch and verify. Separate what they know (training data) from what they can prove (fetched data).<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-knowledge-doesn-t-transfer-between-agents\"><span class=\"ez-toc-section\" id=\"Knowledge_doesnt_transfer_between_agents\"><\/span>Knowledge doesn\u2019t transfer between agents<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This fix I figured out on day one (use a browser user-agent string to avoid CDN blocks) had to be re-taught to every new agent. Day 34, a brand new agent hit the exact same problem.<\/p>\n<p>Agents don\u2019t share memories. Encode shared lessons in a common gotchas file that multiple agents can reference.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-output-format-drifts-between-runs\"><span class=\"ez-toc-section\" id=\"Output_format_drifts_between_runs\"><\/span>Output format drifts between runs<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The same prompt can result in different field names: \u201cnote\u201d vs. \u201cassessment.\u201d \u201clead_score\u201d vs. \u201cqualification_rating.\u201d If you run it twice, get two different schemas.<\/p>\n<p>The fix: Create strict output templates with exact field names. Not \u201cwrite a report.\u201d \u201cUse this exact template with these exact fields.\u201d<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-agents-confidently-report-issues-that-don-t-exist\"><span class=\"ez-toc-section\" id=\"Agents_confidently_report_issues_that_dont_exist\"><\/span>Agents confidently report issues that don\u2019t exist<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The first three audits delivered false positives with total confidence.<\/p>\n<p>The fix wasn\u2019t a better prompt. It was a better boss. A dedicated reviewer agent whose only job is to verify everyone else\u2019s work. The same reason code review exists for human developers.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-bare-http-requests-get-blocked-everywhere\"><span class=\"ez-toc-section\" id=\"Bare_HTTP_requests_get_blocked_everywhere\"><\/span>Bare HTTP requests get blocked everywhere<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Every modern CDN blocks requests without a browser user-agent string. The crawler learned this on audit number two when an entire site returned 403s.<\/p>\n<p>All it required was a one-line fix, and now it\u2019s in the gotchas file. Every new agent reads it on day one.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-don-t-guess-url-paths\"><span class=\"ez-toc-section\" id=\"Dont_guess_URL_paths\"><\/span>Don\u2019t guess URL paths<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Agents love to construct URLs they think should exist: \/about-us, \/blog, \/contact. Half the time, those URLs 404.<\/p>\n<p>My rule is: Fetch the homepage first, read the navigation, follow real links. Never guess.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-done-vs-in-review-matters-nbsp\"><span class=\"ez-toc-section\" id=\"%E2%80%98Done_vs_%E2%80%98in_review_matters\"><\/span>\u2018Done\u2019 vs. \u2018in review\u2019 matters\u00a0<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Agents marked tasks as \u201cdone\u201d when posting their findings. Wrong. \u201cDone\u201d means approved. \u201cIn review\u201d means waiting for human verification.<\/p>\n<p>This small distinction has a huge impact on workflow clarity when you have 10 agents posting work simultaneously.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-categories-must-be-hyper-specific\"><span class=\"ez-toc-section\" id=\"Categories_must_be_hyper-specific\"><\/span>Categories must be hyper-specific<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>\u201cFintech\u201d is useless for prospecting because it\u2019s too broad. \u201cPI law firms in Houston\u201d works. Every company in a category should directly compete with every other company.<\/p>\n<p>My first attempt at sales categories was \u201cPersonal finance &amp; fintech.\u201d A crypto exchange doesn\u2019t compete with a budgeting app. Lesson learned in 20 minutes.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-never-ask-an-llm-to-compile-data\"><span class=\"ez-toc-section\" id=\"Never_ask_an_LLM_to_compile_data\"><\/span>Never ask an LLM to compile data<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Unless you want fabricated results. I asked an agent to summarize findings from five separate reports into one document. It invented findings that weren\u2019t in any of the source reports.<\/p>\n<p>Always build data compilations programmatically. Script it. Never prompt it.<\/p>\n<h3 class=\"wp-block-heading\" id=\"h-agents-will-try-things-you-never-planned\"><span class=\"ez-toc-section\" id=\"Agents_will_try_things_you_never_planned\"><\/span>Agents will try things you never planned<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The research agent tried to call an API we never set up. It assumed we had access because it knew the API existed.<\/p>\n<p>The fix: Be explicit about what tools are available. If a script doesn\u2019t exist in the scripts folder, the agent can\u2019t use it. Boundaries prevent creative failures.<\/p>\n<h2 id=\"build-the-reviewer-first\" class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Build_the_reviewer_first\"><\/span>Build the reviewer first<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This is counterintuitive. When you\u2019re excited about building, you want to build the workers. The crawler. The analyzers. The fun parts.<\/p>\n<p>Build the reviewer first. Without a review layer, you have no way to measure quality. You ship the first audit and it looks great. But 40% of the findings are wrong. You don\u2019t know that until a client or a colleague spots it.<\/p>\n<p>Our review agent reads every finding from every specialist agent. It checks:<\/p>\n<ul class=\"wp-block-list\">\n<li>Does the evidence support the claim?<\/li>\n<li>Is the severity appropriate for the actual impact?<\/li>\n<li>Are there duplicates across different specialists?<\/li>\n<li>Did the agent check what it says it checked?<\/li>\n<\/ul>\n<p>That single agent was the biggest quality improvement I made. Bigger than any prompt tweak. Bigger than any new tool.<\/p>\n<p>The human approval rate across 270 internal linking recommendations: 99.6%. That number exists because a reviewer verifies every single one.<\/p>\n<p>I\u2019ve seen the same pattern with human SEO teams for 20 years. The teams that produce great work aren\u2019t the ones with the best analysts. They\u2019re the ones with the best review process. The analysis is table stakes. The review is the product.<\/p>\n<pre class=\"wp-block-code\"><code>BUILD ORDER (WHAT I LEARNED THE HARD WAY)\n\n  What I did first:     Build workers \u2192 Ship output \u2192 Discover quality problems \u2192 Build reviewer\n  What I should have done: Build reviewer \u2192 Build workers \u2192 Ship reviewed output \u2192 Iterate both\n\n  The reviewer defines quality. Build it first. Everything else gets measured against it.<\/code><\/pre>\n<p><strong>Tip: <\/strong>If you\u2019re building multiple agents, the reviewer should be the first agent you build. Define what \u201cgood output\u201d looks like before you build the thing that produces output. Otherwise, you\u2019re shipping hallucinations with formatting. I learned this across three audits that were embarrassing in hindsight.<\/p>\n<h2 id=\"the-validation-standard-our-unfair-advantage\" class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_validation_standard_Our_unfair_advantage\"><\/span>The validation standard (Our unfair advantage)<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The reviewer catches technical errors. But there\u2019s a higher bar than \u201ctechnically correct.\u201d<\/p>\n<p>We have a real SEO agency with real clients and a team with 50 years of combined experience. Every agent finding gets validated against one question: \u201cWould we stake our reputation on this?\u201d<\/p>\n<p>Would we actually send this to a client, put our name on the report, and tell the developer to build it?<\/p>\n<p>Below are four tests we use for every finding:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>The Google engineer test: <\/strong>If this client\u2019s cousin works at Google, would they read this finding and nod? Would they say, \u201cYes, this is a real issue, this makes sense\u201d? If the answer is no, it doesn\u2019t ship.<\/li>\n<li><strong>The developer test: <\/strong>Can a developer reproduce this without asking a single follow-up question? \u201cFix your canonicals\u201d fails. \u201cChange CANONICAL_BASE_URL from http to https in your production .env\u201d passes.<\/li>\n<li><strong>The agency reputation test: <\/strong>Would we defend this finding in a client meeting? If I\u2019d be embarrassed explaining it to a technical CMO, it gets cut.<\/li>\n<li><strong>The implementation test: <\/strong>Is this specific enough to actually fix? Not \u201cimprove your page speed\u201d but \u201cyour hero video is 3.4MB, which is 72% of total page weight. Serve a compressed version to mobile. Here\u2019s the file.\u201d<\/li>\n<\/ul>\n<p>This is our unfair advantage. We\u2019re not building agents in a vacuum. Most people building AI SEO tools have never run a real audit. They don\u2019t know what \u201cgood\u201d looks like. We do. We\u2019ve been delivering it for 20 years with real clients. That\u2019s why our approval rate is 99.6%.<\/p>\n<h2 id=\"sandbox-testing-train-on-planted-bugs\" class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Sandbox_testing_Train_on_planted_bugs\"><\/span>Sandbox testing: Train on planted bugs<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You don\u2019t train an agent on real client sites. You build a test environment where you KNOW the answers. We built two sandbox websites with SEO issues we planted on purpose:<\/p>\n<ul class=\"wp-block-list\">\n<li>A WordPress-style site with 27+ planted issues: missing canonicals, redirect chains, orphan pages, duplicate content, broken schema markup.<\/li>\n<li>A Node.js site simulating React\/Next.js\/Angular patterns with ~90 planted issues: empty SPA shells, hash routing, stale cached pages, hydration mismatches, cloaking.<\/li>\n<\/ul>\n<p>The training loop:<\/p>\n<ul class=\"wp-block-list\">\n<li>Run agent against sandbox.<\/li>\n<li>Compare agent\u2019s findings to known issues.<\/li>\n<li>Agent missed something? Fix the instructions.<\/li>\n<li>Agent reported a false positive? Add it to gotchas.md.<\/li>\n<li>Re-run. Compare again.<\/li>\n<li>Only when it passes the sandbox consistently does it touch real data.<\/li>\n<\/ul>\n<p>Think of it like a driving test course. Every accident on real roads becomes a new obstacle on the course. New drivers face every known challenge before they hit the highway.<\/p>\n<p>The sandbox is a living test suite. Every verified issue from a real audit gets baked back in. It only gets harder. The agents only get better.<\/p>\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"656\" height=\"856\" http: alt=\"Image 19\" class=\"wp-image-476253\" src=\"https:\/\/searchengineland.com\/wp-content\/seloads\/2026\/05\/image-19.png.webp\"><img fetchpriority=\"high\" decoding=\"async\" width=\"656\" height=\"856\" src=\"https:\/\/searchengineland.com\/wp-content\/seloads\/2026\/05\/image-19.png.webp\" alt=\"Image 19\" class=\"wp-image-476253\"><\/figure>\n<\/div>\n<h2 id=\"consistency-the-unsexy-secret\" class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Consistency_The_unsexy_secret\"><\/span>Consistency: The unsexy secret<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Nobody writes about this because it\u2019s boring. But consistency is what separates a demo from a product.<\/p>\n<p>Three things that make output consistent:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>Templates: <\/strong>Every agent has an output template in templates\/output.md: Exact fields, structure, and severity scale. If the output looks different every run, you don\u2019t need a better prompt. You need a template file.<\/li>\n<li><strong>Run logs:<\/strong> After every execution, the agent appends a summary to memory\/runs.log. Timestamp, site, pages crawled, issues found, duration. The next run reads this log. It knows what happened last time. It can compare and provide outputs like, \u201cFound 14 issues last run. Found 16 this run. 2 new issues identified.\u201d<\/li>\n<li><strong>Schema enforcement:<\/strong> Field names are locked: \u201cseverity\u201d not \u201cpriority,\u201d \u201curl\u201d not \u201cpage_url,\u201d \u201cdescription\u201d not \u201csummary.\u201d When you let field names drift, downstream tooling breaks. Templates solve this permanently.<\/li>\n<\/ul>\n<p>If your agent output looks different every run, you need a template file, not a better prompt. I cannot stress this enough. The single fastest way to improve quality for any agent is a strict output template.<\/p>\n<h2 id=\"the-stack-that-makes-it-work\" class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_stack_that_makes_it_work\"><\/span>The stack that makes it work<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>A quick note on infrastructure, because the tools matter.<\/p>\n<p>Our agents run on OpenClaw. It\u2019s the runtime that handles wake-ups, sessions, memory, and tool routing. Think of it as the operating system the agents run on. When an agent finishes one task and needs to pick up the next, OpenClaw handles that transition. When an agent needs to remember what it did last session, OpenClaw provides that memory.<\/p>\n<p>Paperclip is the company OS. Org charts, goals, issue tracking, task assignments. It\u2019s where agents coordinate. When the crawler finishes mapping a site and needs to hand off to the specialist agents, Paperclip manages that handoff through its issue system. Agents create tasks for each other. Auto-wake on assignment.<\/p>\n<p>Claude Code is the builder. Every script, every agent instruction file, every tool was built with Claude Code running Opus 4.6. I\u2019m a vibe coder with 20 years of SEO expertise and zero traditional programming training. Claude Code turns domain knowledge into working software.<\/p>\n<p>The combination: OpenClaw runs the agents. Paperclip coordinates them. Claude Code builds everything.<\/p>\n<div style=\"background: radial-gradient(circle at 30% 40%, rgba(184, 111, 255, 0.15), rgba(0, 169, 255, 0.15) 40%, #CDE8FD 70%); padding: 30px; width: 100%; max-width: 802px; color: #000000 !important; font-family: Arial, sans-serif; margin: 25px 0 30px 0; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); position: relative; box-sizing: border-box;\">\n<div style=\"width: 100%; max-width: 100%; margin-bottom: 20px; text-align: left; padding-right: 20px; box-sizing: border-box;\">\n<div id=\"semrush-one-headline-bottom\" class=\"headline-responsive\" style=\"font-family: Oswald, sans-serif; font-size: 30px; font-weight: normal; margin: 0; color: #000000 !important; line-height: 1.2;\">\n        See the <span style=\"background: linear-gradient(90deg, #D56EFE 0%, #068EF8 51%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;\">complete picture<\/span> of your search visibility.\n      <\/div>\n<p id=\"semrush-one-subhead-bottom\" style=\"font-family: Roboto, sans-serif; font-size: 18px; font-weight: 300; line-height: 25px; margin: 12px 0 0 0; color: #000000 !important;\">\n        Track, optimize, and win in Google and AI search from one platform.\n      <\/p>\n<\/p><\/div>\n<div style=\"margin-bottom: 15px;\">\n      <span id=\"semrush-one-cta-bottom\" style=\"display: inline-block; background-color: #FF642D; color: white; height: 44px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; padding: 0 24px; font-weight: bold; white-space: nowrap; box-sizing: border-box; text-decoration: none; line-height: 44px;\">Start Free Trial<\/span>\n    <\/div>\n<div style=\"font-size: 12px;\">\n<div style=\"font-family: Roboto, sans-serif; font-weight: 300; color: #000000; margin-bottom: 4px;\">Get started with<\/div>\n<p>      <img loading=\"lazy\" width=\"400\" height=\"52\" decoding=\"async\" http: alt=\"Semrush One Logo\" style=\"height: 16px; width: auto; display: block;\" src=\"https:\/\/searchengineland.com\/wp-content\/seloads\/2025\/11\/semrush-one.webp\"><img loading=\"lazy\" width=\"400\" height=\"52\" decoding=\"async\" src=\"https:\/\/searchengineland.com\/wp-content\/seloads\/2025\/11\/semrush-one.webp\" alt=\"Semrush One Logo\" style=\"height: 16px; width: auto; display: block;\">\n    <\/div>\n<\/p><\/div>\n<style>\n  @media (max-width: 768px) {\n    .headline-responsive {\n      font-size: 30px !important;\n      line-height: 1.3 !important;\n    }\n  }\n<\/style>\n<h2 id=\"the-result\" class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_result\"><\/span>The result<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>This process resulted in 14+ audits completed with 12 to 20 developer-ready tickets per audit, including exact URLs and fix instructions. All produced in hours, not weeks.<\/p>\n<p>We have a 99.6% approval rate on internal linking recommendations on 270 links across two sites, verified by a dedicated review process.\u00a0<\/p>\n<p>We completed more than 80 SEO checks mapped across seven specialist agents. Each check has expected outcomes, evidence requirements, and false positive rules. Every finding is specific (i.e., \u201cthe main app JavaScript bundle is 78% unused. Here are the exact files to fix\u201d).<\/p>\n<p>That level of specificity comes from the skill architecture. The folder structure. The tools. The references. The templates. The review layer. Not the prompt.<\/p>\n<p>If you want to build SEO agent skills that actually work, stop writing prompts and start building workspaces. Give your agents tools, not instructions. Test on sandboxes, not clients.<\/p>\n<p>Build the reviewer first. Enforce templates. Log everything. The first version will fail. The fifth version will surprise you.<\/p>\n<p>This is how you turn agent output into something repeatable. The same system produces the same quality \u2014 whether it\u2019s the first audit or the 14th \u2014 because every step is structured, verified, and encoded.<\/p>\n<p>Not because the AI is smarter. Because the architecture is.<\/p>\n<div class=\"ttd-topics-display\">\n<div class=\"ttd-topics-content\">\n<h5><span class=\"ez-toc-section\" id=\"Topics_on_this_page\"><\/span>Topics on this page<span class=\"ez-toc-section-end\"><\/span><\/h5>\n<div class=\"ttd-topics-links\">Software agentSearch engine optimizationArtificial intelligenceAutomationPrompt engineeringHTMLRobots.txtJavaScriptURLLinkedInGoogleOperating systemWordPressAngularSitemapsHTTPHoustonReactLarge language model<\/div>\n<\/div>\n<div class=\"ttd-topics-show-extra-button\">+14 more<\/div>\n<\/div>\n<\/div>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMN63nwsw68G3Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/buradabiliyorum.com\/en\/category\/technology\/\" target=\"_blank\" >Technology<\/a><\/span> category.<\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/searchengineland.com\/build-seo-agent-skills-476252\" target=\"_blank\" >Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Most AI SEO \u201cskills\u201d are just prompts. Learn the system behind reliable agents: tools, memory, templates, and a built-in review layer. I\u2019ve built 10+ SEO agent skills in 34 days. Six worked on the first try. The other four taught me everything I\u2019m about to show you about the folder structure most LinkedIn posts about&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-725020","post","type-post","status-publish","format-standard","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/725020","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=725020"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/725020\/revisions"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=725020"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=725020"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=725020"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}