<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bobb Kim</title>
    <description>The latest articles on DEV Community by Bobb Kim (@bobb_kim_fcbcd2b6567f5dce).</description>
    <link>https://dev.to/bobb_kim_fcbcd2b6567f5dce</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4127165%2F1763b7c9-4469-4dbc-9a23-66646349b076.jpg</url>
      <title>DEV Community: Bobb Kim</title>
      <link>https://dev.to/bobb_kim_fcbcd2b6567f5dce</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bobb_kim_fcbcd2b6567f5dce"/>
    <language>en</language>
    <item>
      <title>18-Point SEO &amp; AEO Checklist with Jev</title>
      <dc:creator>Bobb Kim</dc:creator>
      <pubDate>Wed, 23 Sep 2026 07:57:27 +0000</pubDate>
      <link>https://dev.to/bobb_kim_fcbcd2b6567f5dce/is-your-site-ready-for-ai-search-a-technical-aeo-checklist-you-can-verify-125o</link>
      <guid>https://dev.to/bobb_kim_fcbcd2b6567f5dce/is-your-site-ready-for-ai-search-a-technical-aeo-checklist-you-can-verify-125o</guid>
      <description>&lt;p&gt;If you want to know whether a site is ready for AI search, start with something testable: can a collector fetch your public HTML, split it into understandable passages, and identify specific facts? That is different from asking whether ChatGPT, Claude, Gemini, or Google AI Overviews actually cite you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://searchd.ai/video/jev-aeo-audit-demo.mp4" rel="noopener noreferrer"&gt;Watch the recorded audit replay&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Recorded searchd.ai audit replay (22 September 2026). SearchD checks public HTML; Jev adds bounded excerpt assessments. Not a live crawl, runtime benchmark, or citation result.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here are 18 checks in five layers. When the &lt;a href="https://searchd.ai/tools/audit" rel="noopener noreferrer"&gt;free SearchD technical AEO audit&lt;/a&gt; retains one or more readable pages, it reports all 18 rows with status, evidence, and next action. If it retains zero readable pages, Page Retrieval is &lt;code&gt;UNKNOWN&lt;/code&gt; and no technical score is issued. Ten rows contain bounded technical measurements. Eight need deeper or external verification. Jev, when available, assesses supplied page excerpts. Its feedback is supplemental and does not determine the technical score; it is not the crawler or the executor of all 18 tests.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;example.com&lt;/code&gt; below as a placeholder. These commands are spot checks, not an equivalent implementation of the SearchD audit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: Can a collector retrieve useful HTML?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. AI-bot access signals.&lt;/strong&gt; Compare root GET responses with representative user agents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;agent &lt;span class="k"&gt;in &lt;/span&gt;OAI-SearchBot ClaudeBot PerplexityBot&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s: '&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$agent&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  curl &lt;span class="nt"&gt;-sS&lt;/span&gt; &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}\n'&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$agent&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; https://example.com/
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SearchD makes analogous root user-agent requests from its own infrastructure. A 200 does not prove official crawler-IP access, every path, or absence of WAF challenges elsewhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Server-rendered text.&lt;/strong&gt; Fetch the response without a browser and inspect whether the primary explanation exists before client JavaScript runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://example.com/ &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; page.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SearchD measures normalized text length in retained HTML. A browser view alone can hide an almost-empty server response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Root &lt;code&gt;robots.txt&lt;/code&gt;.&lt;/strong&gt; Read the actual agent groups and directives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://example.com/robots.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The audit's root-level check does not certify path-by-path access or actual crawler behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Canonical string.&lt;/strong&gt; Inspect the &lt;code&gt;&amp;lt;link rel="canonical"&amp;gt;&lt;/code&gt; in the raw page and compare it with the fetched URL. SearchD checks the declaration string; it does not fetch the canonical target or decide what Google selected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2: Can a page yield a coherent excerpt?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;5. One H1 and local H1–H3 order.&lt;/strong&gt; Check the HTML heading sequence on priority pages. A structurally continuous sequence is not a guarantee of a useful answer beneath it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Semantic fact tables.&lt;/strong&gt; Put comparable specifications in real &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; markup with headers, not a screenshot or a grid of &lt;code&gt;div&lt;/code&gt;s. SearchD detects fact/specification table signals; it does not validate the values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Standalone entity sentences.&lt;/strong&gt; Ask whether an extracted paragraph still names the subject. “It supports exports” is weak outside its page; “Product X supports CSV exports” survives a short excerpt. This row is not site-wide verified by the technical crawl. Jev may assess a bounded excerpt for self-contained statements, specific facts, and fact-table evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Thin retained pages.&lt;/strong&gt; SearchD flags retained pages below 500 normalized text characters. Review intent before expanding them. A contact page can be correctly short; a decision page may need more evidence.&lt;/p&gt;

&lt;p&gt;Jev receives a retained page's URL, title truncated to 70 characters, up to the first 2,500 normalized-text characters, up to six H1–H3 headings, and a table count. It does not visit the URL, execute client JavaScript, or infer what appears beyond that excerpt. Its excerpt feedback is supplemental and does not determine the technical score. For field definitions and scope, see the &lt;a href="https://searchd.ai/blog/jev-technical-aeo-audit" rel="noopener noreferrer"&gt;Jev technical AEO audit guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: Do links explain page roles?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;9. Cannibalization.&lt;/strong&gt; Group URLs by the same query intent and identify the primary answer. The technical report marks this &lt;code&gt;UNKNOWN&lt;/code&gt; because it does not cluster topics or compare target queries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. Orphans.&lt;/strong&gt; Compare a complete indexable-URL inventory with a full internal-link graph. Sitemap/homepage discovery alone cannot prove there are no orphaned pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11. Contextual anchors.&lt;/strong&gt; Look for links within relevant paragraphs or lists, then inspect destination and anchor meaning. SearchD records a structural presence signal that may include external links, not a scored internal-link graph.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 4: Does structured data match visible reality?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;12. Parseable JSON-LD.&lt;/strong&gt; Validate &lt;code&gt;application/ld+json&lt;/code&gt; blocks and inspect declared &lt;code&gt;@type&lt;/code&gt; values. Parseability is a first check, not proof of correct schema fields.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;13. Absolute &lt;code&gt;sameAs&lt;/code&gt; URLs.&lt;/strong&gt; Confirm that entity profile links are valid absolute HTTP(S) URLs, then verify that the profiles are official. SearchD measures URL presence; ownership remains unverified.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;14. Visible-schema parity.&lt;/strong&gt; Compare names, prices, availability, dates, and claims in JSON-LD with the page a visitor sees. This is a separate field-level review, not a &lt;code&gt;PASS&lt;/code&gt; inferred from parsing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 5: Test outcomes outside the HTML audit
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;15. ChatGPT grounding.&lt;/strong&gt; Run a dated, repeatable prompt set and save the response and displayed sources. The technical endpoint does not run this probe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;16. Claude/Cursor extraction.&lt;/strong&gt; Define a source document, task, tool/version, and expected fact; record what was extracted and missed. This is not implied by Jev excerpt feedback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;17. Gemini/Google AI Overview appearance.&lt;/strong&gt; Log query, date, locale, device context, response, and cited sources over time. Do not call a technical score a citation win rate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;18. Webmaster gateways.&lt;/strong&gt; Verify sitemap submission, indexing, and errors in Google Search Console and Bing Webmaster Tools. The free audit does not authenticate to either account.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run the report, then keep two queues
&lt;/h2&gt;

&lt;p&gt;Enter a domain in the &lt;a href="https://searchd.ai/tools/audit" rel="noopener noreferrer"&gt;free SearchD technical AEO audit&lt;/a&gt;. It selects up to 300 same-host candidate URLs from a sitemap or homepage links, retains readable HTML/XHTML, and does not execute client JavaScript. Read the URL-level evidence behind a finding before making a change. The fetched/discovered count applies to that bounded candidate set, not necessarily every URL on your domain.&lt;/p&gt;

&lt;p&gt;Keep &lt;strong&gt;confirmed technical defects&lt;/strong&gt; in one queue and &lt;strong&gt;&lt;code&gt;UNKNOWN&lt;/code&gt;, &lt;code&gt;UNVERIFIED&lt;/code&gt;, or &lt;code&gt;NOT RUN&lt;/code&gt; questions&lt;/strong&gt; in another. Fix the former; design actual tests for the latter. That is more useful than treating a technical readiness score as a prediction of citations, rankings, traffic, or revenue.&lt;/p&gt;

&lt;p&gt;Method: &lt;a href="https://app.beardrive.ai/s/39d0b5a803fcf0db40b29706958ef217" rel="noopener noreferrer"&gt;SearchD technical audit documentation&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>seo</category>
      <category>ai</category>
      <category>webdev</category>
      <category>aeo</category>
    </item>
    <item>
      <title>Why Your AI Visibility Score Changed When Your Code Did Not: 4 Measurement Dials and Noise-Floor Math</title>
      <dc:creator>Bobb Kim</dc:creator>
      <pubDate>Mon, 21 Sep 2026 02:07:44 +0000</pubDate>
      <link>https://dev.to/bobb_kim_fcbcd2b6567f5dce/why-your-ai-visibility-score-changed-when-your-code-did-not-4-measurement-dials-and-noise-floor-6jk</link>
      <guid>https://dev.to/bobb_kim_fcbcd2b6567f5dce/why-your-ai-visibility-score-changed-when-your-code-did-not-4-measurement-dials-and-noise-floor-6jk</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvnmwci443zceli56mnhq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvnmwci443zceli56mnhq.png" alt="AI visibility score jump from 0% to 12% following question set replacement" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is the measurement anomaly that prompted our engineering team to audit our AI visibility benchmarking pipeline:&lt;/p&gt;

&lt;p&gt;An agency our team at SearchD tracks sat at &lt;strong&gt;0.0% visibility&lt;/strong&gt; in AI answers through September 13. Two days later, the tracker showed &lt;strong&gt;12.0%&lt;/strong&gt;. Two days after that, &lt;strong&gt;12.7%&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Nobody on that team had shipped a pull request, published a piece of content, or gained new backlinks in that window. &lt;/p&gt;

&lt;p&gt;The cause was simple: &lt;strong&gt;I had replaced the 50 questions in our automated tracking panel.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The agency specializes in Korean beauty. The new 50-question set specifically addressed cross-border US market entry for Korean beauty brands. The metric moved by 12 percentage points because the test changed, not because the subject did.&lt;/p&gt;

&lt;p&gt;If you treat an AI visibility score like an objective metric—analogous to server uptime or page latency—that artifact is impossible. In practice, an AI visibility score is an output of four technical dials chosen by whoever writes the benchmark pipeline.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dial 1: The Question Set as a Measurement Denominator
&lt;/h2&gt;

&lt;p&gt;Fifty questions submitted across three major generative search engines equals &lt;strong&gt;150 discrete model responses per day&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Swap the question set, and every single score in your database moves:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fihhztknehmyzyo391yvw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fihhztknehmyzyo391yvw.png" alt="Figure 1: Visibility in AI answers before and after question set replacement" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before our audit, our reporting pipeline had automatically stacked the old and new panels into a continuous time-series chart reading &lt;em&gt;"8% to 2%, declining."&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;There was no decline. There were two distinct exams with completely different query spaces. That artifact was treated as a legitimate trend line by both our internal dashboard and a weekly report built on top of it before someone checked the timestamp on the question IDs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rule for benchmarking pipelines:&lt;/strong&gt; If your prompt pool changes between runs, you do not have a trend line. You have two isolated datasets displayed side-by-side.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dial 2: The Prompt Verb and Slot-Filling Dynamics
&lt;/h2&gt;

&lt;p&gt;In generative language models, prompt syntax dictates the structural schema of the generated answer.&lt;/p&gt;

&lt;p&gt;We tested this across our 50-question panel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;46 questions&lt;/strong&gt; began with the phrase &lt;code&gt;"Which agency..."&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4 questions&lt;/strong&gt; began with &lt;code&gt;"Who can..."&lt;/code&gt; or &lt;code&gt;"Who fixes..."&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The results diverged completely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The 46 &lt;code&gt;"Which agency"&lt;/code&gt; prompts returned &lt;strong&gt;41 full slates of named vendors&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The 4 &lt;code&gt;"Who can / Who fixes"&lt;/code&gt; prompts returned &lt;strong&gt;0, 0, 0, and 3 vendor names&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzmytbq2ik7nvzfk2fn4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzmytbq2ik7nvzfk2fn4i.png" alt="Figure 2: Same situation, one verb apart. Which agency vs Who can" width="800" height="661"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Consider two prompts describing the identical technical challenge—a Korean sunscreen selling on Amazon US that AI assistants never mention:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prompt A: "Which agency can make a Korean sunscreen visible in AI answers on Amazon US?"
Response: Names 4 specific agencies (Agency A, Dahna, Search Agency, etc.)

Prompt B: "Who can make a Korean sunscreen visible in AI answers on Amazon US?"
Response: "Your in-house digital marketing and ecommerce team should handle it." (0 vendors)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A third prompt variation returned generic job titles instead of corporate entities: &lt;em&gt;entity SEO consultant, technical SEO specialist, digital PR agency&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When a prompt structure does not create a semantic slot for an agency, the model cannot name one. A score of zero on Prompt B is a syntactic constraint of the prompt, not an evaluation of your brand's market authority.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dial 3: The Counter, Parser Failures, and the Noise Floor
&lt;/h2&gt;

&lt;p&gt;In an evaluation pipeline running 150 responses per day:&lt;/p&gt;

&lt;p&gt;$$\text{Weight of 1 mention} = \frac{1}{50 \times 3} = \frac{1}{150} \approx 0.67\%$$&lt;/p&gt;

&lt;p&gt;A single mention swinging between runs alters the day's score by &lt;strong&gt;0.67 points&lt;/strong&gt;. Any day-to-day swing under 1.3 points is stochastic model noise.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwc1fuf8moxfgg2vi3po5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwc1fuf8moxfgg2vi3po5.png" alt="Figure 3: Noise floor and rolling window scale" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At SearchD, our data pipeline evaluates tracking metrics exclusively over a &lt;strong&gt;7-day rolling window&lt;/strong&gt;, enforcing a strict noise floor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;0.0 - 1.3 pts:&lt;/strong&gt; Pure stochastic noise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1.3 - 2.0 pts:&lt;/strong&gt; Indeterminate; not called as progress.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;≥ 2.0 pts:&lt;/strong&gt; Minimum statistically actionable threshold.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Regex Parser Trap
&lt;/h3&gt;

&lt;p&gt;Counting also fails in subtle edge cases. In one automated batch, ChatGPT shortlisted three agencies and explicitly named a winner in bold text. &lt;/p&gt;

&lt;p&gt;Our automated tracker logged &lt;strong&gt;0 points&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Why? The model generated an unexpected markdown table with an unclosed cell delimiter mid-sentence. The regex parser looking for &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt; entity tags walked straight past the candidate name. The prompt worked, the model recommended the entity, but the metric recorded zero.&lt;/p&gt;

&lt;p&gt;Here is how we now enforce sanity checks in Python before computing visibility deltas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;evaluate_visibility_signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;daily_mentions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total_runs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;daily_mentions&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;total_runs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
    &lt;span class="n"&gt;single_mention_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;total_runs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;  &lt;span class="c1"&gt;# 0.67%
&lt;/span&gt;    &lt;span class="n"&gt;noise_floor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;single_mention_val&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;          &lt;span class="c1"&gt;# 2.0%
&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;raw_score&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;single_mention_value&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;single_mention_val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;noise_floor_threshold&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;noise_floor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;is_statistically_actionable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;noise_floor&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Dial 4: Entity Classification (Noun-Level Sorting)
&lt;/h2&gt;

&lt;p&gt;Language models categorize entities into ontology buckets. During our audit, models consistently categorized SearchD as a &lt;strong&gt;"tool"&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"AEO tool for Asian brands targeting US customers"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"early stage specialist tool"&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When every question in the panel asks &lt;em&gt;"which agency"&lt;/em&gt;, an entity filed under the noun &lt;em&gt;"tool"&lt;/em&gt; is not a losing candidate—it is excluded from the candidate pool before ranking begins.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 40% Vanity Metric vs. Our 2.0% Baseline
&lt;/h2&gt;

&lt;p&gt;Whoever configures your AI visibility report controls all four dials:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6f93kf91zhxidji7rvga.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6f93kf91zhxidji7rvga.png" alt="Figure 4: Four dials summary card" width="799" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If our goal were to create a flattering dashboard, it would take five minutes: we could select ten narrow, brand-adjacent questions, run them on a favorable engine, and show a &lt;strong&gt;30% to 40% visibility rate&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Many agency dashboards do exactly this.&lt;/p&gt;

&lt;p&gt;Instead, when we ran our unbranded 50-question panel across 3 engines (150 daily runs) on September 17, SearchD scored &lt;strong&gt;2.0 percent&lt;/strong&gt; (3 mentions out of 150). &lt;/p&gt;

&lt;p&gt;On September 17, one engine did place SearchD first: &lt;em&gt;"the most directly relevant agency I found is SearchD"&lt;/em&gt;. That accounted for two mentions (+1.33 points). Because 1.33 points sits squarely below our 2.0-point noise floor, our pipeline recorded it as a stochastic event, not verified optimization progress.&lt;/p&gt;

&lt;p&gt;Publishing a grounded 2.0% baseline with defined noise boundaries is far more valuable than optimizing a vanity dashboard you designed yourself to win.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Bobb Kim is an AI Engineer with SearchD and Runbear, focusing on AI evaluation pipelines and LLM entity resolution.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aiwebdevpythondatascience</category>
    </item>
    <item>
      <title>Keep ChatGPT UI observations out of your API denominator</title>
      <dc:creator>Bobb Kim</dc:creator>
      <pubDate>Thu, 17 Sep 2026 08:01:44 +0000</pubDate>
      <link>https://dev.to/bobb_kim_fcbcd2b6567f5dce/keep-chatgpt-ui-observations-out-of-your-api-denominator-4gdd</link>
      <guid>https://dev.to/bobb_kim_fcbcd2b6567f5dce/keep-chatgpt-ui-observations-out-of-your-api-denominator-4gdd</guid>
      <description>&lt;p&gt;A buyer-facing question produced a useful puzzle, not a benchmark result:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;what is the best aeo/geo agency for korean beauty products?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On 14 September 2026, we recorded &lt;strong&gt;one&lt;/strong&gt; answer in the consumer ChatGPT UI. On 16 September, we ran the same question &lt;strong&gt;five independent times&lt;/strong&gt; through the Responses API with &lt;code&gt;web_search&lt;/code&gt;, &lt;code&gt;gpt-5.5&lt;/code&gt;, &lt;code&gt;tool_choice: required&lt;/code&gt;, &lt;code&gt;store: false&lt;/code&gt;, no prior-response reference, and no brand supplied. The user location was not fixed.&lt;/p&gt;

&lt;p&gt;The important implementation detail is simple: these are two collection surfaces. They must remain in two denominators. A UI answer is not run 1 of an API batch, so this is not a “six-run success rate.”&lt;/p&gt;

&lt;p&gt;That distinction preserves the interesting observation instead of overstating it. The UI named five agencies. In the later API batch, only Agency B from those original five was named in all five runs; the other four were not named in that batch. A newly appearing agency was also named 5/5, so Agency B was not the only API repeat. SearchD was absent from both the initial five and the five API answers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The recorded comparison
&lt;/h2&gt;

&lt;p&gt;In SearchD’s review, Domain Rating (DR) was looked up on 16 September. It is a proxy metric, not a complete measure of authority. The table is a source-case record, not a ranking model.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agency&lt;/th&gt;
&lt;th&gt;Position in the 14 Sep UI answer&lt;/th&gt;
&lt;th&gt;DR on 16 Sep&lt;/th&gt;
&lt;th&gt;Named in five independent API runs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agency A&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;0/5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agency B&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;0.7&lt;/td&gt;
&lt;td&gt;5/5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agency C&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;47&lt;/td&gt;
&lt;td&gt;0/5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agency D&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0.8&lt;/td&gt;
&lt;td&gt;0/5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agency E&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;76&lt;/td&gt;
&lt;td&gt;0/5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SearchD&lt;/td&gt;
&lt;td&gt;not listed&lt;/td&gt;
&lt;td&gt;0.1&lt;/td&gt;
&lt;td&gt;0/5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The displayed-citation record adds a separate fact: Agency B’s &lt;strong&gt;domain&lt;/strong&gt; appeared among citations in 5/5 API runs. The available record says its service page was the most commonly cited URL. It does &lt;strong&gt;not&lt;/strong&gt; establish that one exact URL was cited in all five runs.&lt;/p&gt;

&lt;p&gt;What can we say? A low-DR agency persisted across this particular five-run API batch while higher-DR initial UI names did not. What cannot we say? That DR causes, prevents, or predicts AI recommendations; that the API reproduces the consumer UI; or that a page change will create a recommendation.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, investigate the usual explanations
&lt;/h2&gt;

&lt;p&gt;In SearchD’s review, the source case checked four plausible explanations before inspecting page content:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backlinks:&lt;/strong&gt; the recorded lookup reported zero dofollow referring domains.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;US rankings:&lt;/strong&gt; the recorded lookup reported zero US organic keywords.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Industry roundups:&lt;/strong&gt; the agency was absent from three checked category roundups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track record:&lt;/strong&gt; the source reported a January 2026 founding date.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are limited checks, not proof that every authority signal or explanation has been eliminated. They are still valuable because they explain why the next step was page inspection rather than another generic SEO claim.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the inspection found
&lt;/h2&gt;

&lt;p&gt;SearchD’s inspection offers three candidate explanations for why a site might be easy for a model or reviewer to describe. They are observations about information structure, not retrieval traces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvj35yzyjnhllx2t5pusq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvj35yzyjnhllx2t5pusq.png" alt="Original editorial comparison of a link-list file and explicit company identity fields." width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Accessible equivalent: compare a file that is mostly a Markdown link list with a file that puts company facts in labeled, line-level fields. The right-hand structure makes legal name, founder roles, founding date, location, languages, contact, and services directly extractable.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Source caption: Original editorial illustration by Liam Hwang for the SearchD team case, 17 September 2026. It compares information structures only; it does not demonstrate model retrieval or an &lt;code&gt;llms.txt&lt;/code&gt; effect.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. An entity-readable file, not merely a link list
&lt;/h3&gt;

&lt;p&gt;In SearchD’s page review, the inspected file contrasted a sitemap-like &lt;code&gt;llms.txt&lt;/code&gt; with an entity-oriented version. The latter surfaced legal name, both founders and roles, founding date, location, working languages, contact address, and services as explicit attributes. The source reported a 3,272-word summary and a 16,291-word full version, with an update date inside the file.&lt;/p&gt;

&lt;p&gt;Those lengths are descriptive facts, not an ideal word-count target, and publishing &lt;code&gt;llms.txt&lt;/code&gt; is not proof that a model consumed it. The practical lesson is narrower: when a reviewer needs to answer “who is this company?” a labeled fact is less ambiguous than a marketing paragraph or a list of links.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Identity questions and regulated-service limits were answered directly
&lt;/h3&gt;

&lt;p&gt;SearchD’s page review found that the category page reportedly used seven FAQ topics. Two are especially useful for avoiding inference: whether the company is a Korean marketing agency, and whether it handles FDA, customs, tax, or legal work. A separate source observation stated that an email/SMS service was paused.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faoyy7816ruesesn72x52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faoyy7816ruesesn72x52.png" alt="Seven FAQ topics with company identity and FDA customs tax legal scope highlighted, plus a paused-service statement." width="800" height="683"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Accessible equivalent: seven FAQ topics are grouped into sales questions and two classification questions. One identifies what the company is; another states what regulated work it does not do. A separate notice identifies a paused service.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Source caption: Original source-case transcription of the FAQ topics and service boundaries. This is not a product screenshot and does not measure a recommendation effect.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;FAQ markup itself is not a demonstrated cause. The underlying visible answers are useful because they let a reader distinguish identity, scope, and exclusions without inventing missing facts.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The absence of named case studies was structured, not hidden
&lt;/h3&gt;

&lt;p&gt;SearchD’s review found that the site reportedly separated four claim types: founder experience in prior roles, deliberately withheld former-client identities, illustrative deliverables, and measured results. The case did not disclose named client case studies.&lt;/p&gt;

&lt;p&gt;This is not evidence of capability or outcomes. It is an example of a site making the limits of its evidence legible. For an assistant, reviewer, or procurement team, “illustrative deliverable” is a safer fact than an unlabeled example presented like proof.&lt;/p&gt;

&lt;h2&gt;
  
  
  The counterintuitive detail
&lt;/h2&gt;

&lt;p&gt;The inspected site used “AEO” zero times. The model’s reported descriptions, such as entity consistency, citation-friendly content, and off-site corroboration, were not present as phrases either. Meanwhile, SearchD uses that vocabulary on its own site but was not named in these observations.&lt;/p&gt;

&lt;p&gt;That makes “answerability beat vocabulary” a reasonable &lt;strong&gt;case hypothesis&lt;/strong&gt;, not a keyword rule. The pages inspected are not the entire web, and nothing here establishes keyword determinism.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turn the case into a content-quality run
&lt;/h2&gt;

&lt;p&gt;For a Korean beauty brand selling in the US, SearchD’s team translates the abstract pattern into buyer questions:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpqurgicx1e9k9rj8no9h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpqurgicx1e9k9rj8no9h.png" alt="Four source-case checks: explicit brand origin, answerable market and product facts, stated boundaries, and crawlable content." width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Accessible equivalent: four checks ask whether a brand states its Korean origin, gives precise market and product facts, names exclusions, and exposes visible HTML that agrees with structured data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Source caption: Original SearchD four-check framework from the source case. These are information-quality checks, not a guarantee of citations or recommendations.&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Origin:&lt;/strong&gt; Does body text say whether the brand is Korean? Brand origin is not the same as manufacturing location.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Market version:&lt;/strong&gt; Can a shopper determine the US formula or packaging version, shipping and authorized-retailer status, and product-specific availability?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Negative boundaries:&lt;/strong&gt; Does the page explicitly say what it does not sell, ship, claim, or provide? Do not imply FDA, customs, tax, or legal services where none exist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency:&lt;/strong&gt; Does visible HTML say the same thing as the relevant structured data?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is an illustrative record schema. It is deliberately a planning artifact, not a client result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"entity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Example K-beauty Brand"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The US retail formula for Product X is fragrance-free."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/us/product-x"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source_owner"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Regulatory and product teams"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"visible_html_verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"structured_data_verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"publish_change"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Add the market-version statement to the US product page."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"retest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Repeat the same separated-surface collection after publication."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A practical run has five fields: &lt;strong&gt;owner, fact, source, publish, retest&lt;/strong&gt;. The owner validates the fact. The source points to evidence. The page receives an explicit statement. The change is published through normal review. Then we rerun the protocol without pooling UI and API observations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Minimal checks before interpreting a batch
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Surface&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;consumer_ui&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;responses_api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Observation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;surface&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Surface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;observed_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;run_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;named_entities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;citation_domains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;citation_urls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;assertComparable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Observation&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;surface&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Aggregate one surface at a time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Keep the prompt fixed within the batch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SearchD’s measurement notes keep raw responses privately if they contain sensitive data. Publicly report a compact ledger: prompt, date, surface, model and tools where known, run count, entity recurrence, citation-domain recurrence, exact-URL uncertainty, and unfixed variables such as location.&lt;/p&gt;

&lt;p&gt;The next measure is not “did the site win?” It is whether the audited facts are accurate, visible, structurally consistent, and answerable under repeatable collection conditions. This case observed no uplift, traffic, sales, or causal effect. It gives us a disciplined way to document the next test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source and disclosure
&lt;/h2&gt;

&lt;p&gt;Based on &lt;a href="https://www.linkedin.com/pulse/why-ai-recommends-brands-authority-backlinks-rankings-liam-hwang-8ctfc/" rel="noopener noreferrer"&gt;Liam Hwang’s original SearchD case&lt;/a&gt;, published 17 September 2026. The illustrations are Liam’s original public editorial figures; text and examples are adapted for this channel.&lt;/p&gt;

&lt;p&gt;Bobb Kim is an AI Engineer who works with &lt;a href="https://searchd.ai/about" rel="noopener noreferrer"&gt;SearchD&lt;/a&gt;. Prepared with AI assistance. This is our team’s research, not an independent agency endorsement or client-results report.&lt;/p&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>Debugging US K-beauty AI Answers: Missing Mentions vs. Wrong Product Facts</title>
      <dc:creator>Bobb Kim</dc:creator>
      <pubDate>Wed, 16 Sep 2026 04:04:33 +0000</pubDate>
      <link>https://dev.to/bobb_kim_fcbcd2b6567f5dce/treat-ai-agency-recommendations-as-a-retrieval-trace-not-a-ranking-3mm4</link>
      <guid>https://dev.to/bobb_kim_fcbcd2b6567f5dce/treat-ai-agency-recommendations-as-a-retrieval-trace-not-a-ranking-3mm4</guid>
      <description>&lt;p&gt;Three months of English content and a flat answer engine optimization (AEO) score do not identify a defect. Neither does strong Korean Google visibility. A US assistant might omit the product, confuse its identity, or name it while repeating the Korean formula. Those need different work queues.&lt;/p&gt;

&lt;p&gt;Start with observable answers and displayed sources, not a presumed ranking or complete retrieval trace. Liam Hwang’s &lt;a href="https://medium.com/searchd/ask-an-ai-which-agency-to-hire-what-decides-the-names-that-come-back-b2e883ee176a" rel="noopener noreferrer"&gt;original SearchD source-map article&lt;/a&gt; motivates comparing source sets across assistants. That qualitative observation is not evidence about these K-beauty scenarios or their outcomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Freeze the questions, separate the defects
&lt;/h2&gt;

&lt;p&gt;For SearchD’s source-gap diagnosis, keep exact question wording, assistant, date, requested market, language, and session conditions. “Which Korean moisturizer should I buy in the US?” tests discovery. “Which formula is sold in the US?” tests accuracy. Do not merge their results into one score. Keep the panel composition fixed: changing the question mix can move a headline score even when every underlying answer stays the same. Record exclusions by engine, too.&lt;/p&gt;

&lt;p&gt;For intermittent mentions, repeat unchanged questions in comparable clean sessions before attributing a change to an edit. Record the interface and model version when exposed; requested US context is not proof of the assistant’s actual localization.&lt;/p&gt;

&lt;p&gt;The examples below are illustrative, derived from buyer questions, not customer records, measured results, or an official platform schema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Store capture state beside the approved product record
&lt;/h2&gt;

&lt;p&gt;This illustrative record makes SearchD’s distinction between missing evidence and an absent mention explicit; it is not a production schema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"question_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"us-formula-01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"question"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Which version of Example Brand Daily Cream is sold in the US?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"assistant"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"assistant-name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"observed_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-09-15T00:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"requested_market"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"US"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"language"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"en-US"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"capture_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"failed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"failure_reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"timeout"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"answer_text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"named_entities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"displayed_sources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sources_capture_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"not_collected"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"product_record"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"brand_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example-korean-brand"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"brand_origin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"KR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"official_domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"product_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"daily-cream-us"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"market"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"US"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"formula_revision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"effective_from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"approved_claims"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"authorized_retailers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"approval_status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pending"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"approved_by"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"approved_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The product record becomes the comparison reference only after approval. Replace placeholders with versioned records and evidence links; never infer US facts from the Korean page. The client’s compliance owner approves formula, SPF, certification, and regulatory wording. Pending fields cannot establish that an answer is wrong.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;ok&lt;/code&gt; only for a complete answer capture. Store &lt;code&gt;failed&lt;/code&gt;, &lt;code&gt;blocked&lt;/code&gt;, or &lt;code&gt;partial&lt;/code&gt; separately, with reasons and retained fragments. A timeout is not an absent mention. An empty source list means no sources were displayed only when collection was complete; otherwise use null and a collection status.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compare pages before domains
&lt;/h2&gt;

&lt;p&gt;For a SearchD source comparison, preserve full displayed URLs and the answer sentences attached to them. Host overlap is a secondary diagnostic, not a measure of factual agreement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;urllib.parse&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urlparse&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;capture_status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sources_capture_status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;complete&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;displayed_sources&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;urlparse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;urls&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;urlparse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;jaccard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;union&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;union&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;union&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;named_rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;records&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;eligible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;records&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;capture_status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;named_entities&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;eligible&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target_id&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;named_entities&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
               &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;eligible&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eligible&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;named_entities&lt;/code&gt; contains reviewed, normalized IDs, not raw string matches. A namesake US company must not count as the Korean brand. Two empty source sets return no overlap score, rather than suggesting perfect evidence agreement. Report eligible and excluded capture counts alongside any rate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Route observations to the right owner
&lt;/h2&gt;

&lt;p&gt;SearchD can ship approved changes on brand-owned pages; external corrections remain requests to the page owner. The diagnostic cases below keep those responsibilities separate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Absent product, plenty of English content.&lt;/strong&gt; First inspect US page accessibility: response status, crawl directives, indexing eligibility, canonical targets, internal links, and whether product facts exist in readable HTML. Compare the US page with the Korean page, without assuming Korean search rankings transfer. A failed access check is actionable; passing it does not guarantee citation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accurate translation, ambiguous identity.&lt;/strong&gt; Direct translation can omit market context. Give each answer passage an explicit brand, product, US variant, and effective date. Align the official domain, Korean origin, and product identifiers across owned pages. Distinguish the unrelated US namesake in factual copy where needed; do not count its mentions as wins.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Named product, wrong formula.&lt;/strong&gt; Compare the exact answer claim against the approved US record and inspect the displayed page. A Korean-market source suggests a market-selection mismatch; an outdated US retailer listing suggests stale facts. Without displayed support, mark the source of the error unknown, rather than inventing a retrieval explanation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Old retailer facts.&lt;/strong&gt; Save the listing URL, dated excerpt, conflicting approved record, proposed correction, and page owner. Correct brand-owned pages directly after approval. Send retailer or distributor owners a documented correction request, then verify the public listing. Request submission is not acceptance, and acceptance is not proof that assistants changed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7xiax3u15ybfms26prce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7xiax3u15ybfms26prce.png" alt="Workflow from a US buyer question through capture status, answer and source collection, and assignment of the responsible owner; failed captures are missing evidence, not zero mentions" width="800" height="1067"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Illustrative engineering workflow, not a customer-result chart. JSON and Python remain editable text above.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep measurement and delivery separate
&lt;/h2&gt;

&lt;p&gt;To evaluate SearchD’s work, track named entities, displayed citations, factual accuracy, and referrals as separate events. A displayed citation is neither a visit nor the assistant’s complete retrieval history. Maintain a shipping log and an observation log; compare repeated answers per assistant without treating timing as causation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosed SearchD scope
&lt;/h2&gt;

&lt;p&gt;I work with &lt;a href="https://searchd.ai/k-beauty-aeo-agency" rel="noopener noreferrer"&gt;SearchD&lt;/a&gt;, a San Francisco-based AEO agency for Korean consumer brands selling in the US. Its &lt;a href="https://searchd.ai/how-it-works" rel="noopener noreferrer"&gt;published method&lt;/a&gt; covers fixed buyer-question measurement, approved English buyer-question pages, and technical fixes shipped on brand-owned properties. Retailers control their listings; editors control independent coverage. It can document correction requests, not guarantee acceptance or AI inclusion. Its public service method specifies 40 questions across five engines. These scenarios demonstrate diagnosis, not verified client outcomes.&lt;/p&gt;

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