mcpField
C
content-semantics

content-semantics

github.com/bartwaardenburg开发0188 次安装1 周前更新
代码仓库

关于 content-semantics

content-semantics 是用于修复 IsAgentReady.com「Content & Semantics」类别问题的 Agent 技能,面向需要改善网页可读性与可操作性的开发者。它根据扫描检查项提供修复流程、验证命令和重新扫描指引。

主要功能

  1. 01按扫描检查项定位问题
  2. 02指导服务端渲染改进
  3. 03检查标题、地标与语义 HTML
  4. 04改善图片替代文本与表单标签
  5. 05提供只读验证及重新扫描指引

适用场景

  1. 01修复扫描发现的语义内容问题
  2. 02为缺少文本的 SPA 补充服务端内容
  3. 03改善网页控件对浏览器 Agent 的可操作性

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bartwaardenburg/isagentready-skills --skill content-semantics

安装后在 Claude Code 中输入/content-semantics确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
checkpoints.md
gotchas.md
semantic-html-guide.md
ssr-strategies.md

详细介绍

内容与语义

修复 IsAgentReady.com 的“内容与语义”类别。Agent 会读取服务端 HTML、DOM 和无障碍树。良好的语义化 HTML 能在这些视图中提供可靠的信号。

适用情形

  • 扫描显示“内容与语义”类别存在未通过项(旧版 ID 3.x)。
  • 页面是空的 SPA 外壳,没有服务端渲染的文本。
  • 缺少标题、地标、替代文本、标签或按钮名称。
  • 浏览器 Agent 难以操作表单或小组件。

不适用情形

  • JSON-LD 或 FAQPage 标记:使用 structured-data。
  • robots.txt、sitemap 或 llms.txt:使用 ai-content-discovery。
  • WebMCP 工具注释:使用 agent-protocols。
  • 只更改视觉设计、不更改 HTML 结构。

说明

  1. 从扫描结果中获取未通过的检查点。每项结果都有一个旧版 ID(3.2)和一个稳定 ID(ia.heading-hierarchy)。
  2. 使用与稳定 ID 相同的锚点,前往对应的修复工作流。
  3. 根据网站调整示例。将 example.com 替换为网站的域名。
  4. 运行验证命令。所有验证命令均为只读。有些检查没有 shell 检查命令。然后使用重新扫描命令。
  5. 使用 isagentready results <domain> --checkpoint <stable-id> 重新扫描,或访问 isagentready.com。

如果提供了 $ARGUMENTS,则将其作为要修复的网址或检查点。

检查点

强度表示 agentready.org 规范级别(MUST、SHOULD、MAY)。强度不会影响评分。

旧版稳定 ID名称AR ID强度
3.1ia.server-rendered-content服务端渲染的内容AR-READ-01, AR-READ-03MUST
3.2ia.heading-hierarchy标题层级AR-READ-03MUST
3.3ia.semantic-html语义化 HTML 元素无MUST
3.4ia.landmarks-aria地标和 ARIA无SHOULD
3.5ia.image-alt图片替代文本无MUST
3.6ia.lang-attribute语言属性无MUST
3.7ia.link-text描述性链接文本无MUST
3.9ia.form-labels表单标签覆盖率无SHOULD
3.10ia.form-autocomplete表单字段自动完成无SHOULD
3.11ia.keyboard-navigation键盘可导航性无SHOULD
3.12ia.document-title文档标题AR-READ-03MUST
3.13ia.button-names按钮无障碍名称无SHOULD
3.14ia.aria-hiddenaria-hidden 误用无SHOULD
3.15ia.widget-state动态小组件状态无SHOULD

修复工作流

3.1 服务端渲染的内容

如果原始 HTML 的 <body> 中有超过 200 个可见文本字符(不运行 JavaScript),则通过检查。<noscript> 回退内容可获得部分分数。

  1. 在原始 HTML 中查找类似 <div id="root"></div> 的空外壳。
  2. 在框架中启用 SSR 或静态生成。Next.js、Nuxt、Astro、Remix、SvelteKit 和 Angular 的相关说明见 references/ssr-strategies.md。
    // Next.js App Router: a server component renders on the server by default
    export default async function Page() {
      const product = await getProduct();
      return <main><h1>{product.name}</h1><p>{product.summary}</p></main>;
    }
    

验证:curl -sf https://example.com/ | sed -e 's/<[^>]*>//g' | tr -s ' \n' | wc -c(预期结果大于 200)

3.2 标题层级

当页面恰好有一个 <h1>、层级没有跳跃且没有空标题时,即通过。

  1. 页面标题保留一个 <h1>。将其他 <h1> 元素改为 <h2>。
  2. 当标题从 <h1> 跳到 <h3> 时,补上缺少的层级:
    <h1>Planner Pro</h1>
      <h2>Features</h2>
        <h3>Timeline view</h3>
      <h2>Pricing</h2>
    
  3. 不要将 logo 图片放在 <h1> 中。

验证:只读 shell 检查不会给出通过或失败的结果。请使用重新扫描命令。

3.3 语义 HTML 元素

当页面包含 <header>、<nav>、<main>、<article> 或 <section>,以及 <footer> 时,即通过。

  1. 将用于布局的 <div> 包装元素替换为语义元素:
    <body>
      <header><nav aria-label="Primary"><a href="/">Home</a></nav></header>
      <main><article><h1>Page title</h1><section><h2>Part</h2></section></article></main>
      <footer><p>Example Inc</p></footer>
    </body>
    

验证:curl -sf https://example.com/ | grep -oE '<(header|nav|main|article|section|footer)[ >]' | sort -u

3.4 地标和 ARIA

当页面至少有三个地标区域,并且有一个或多个 ARIA 属性(如 aria-label、aria-current 或 aria-live)时,即通过。

  1. 先使用 3.3 中的语义元素。它们会隐式提供地标。
  2. 为重复的地标添加标签,并标记当前页面:
    <nav aria-label="Primary"><a href="/" aria-current="page">Home</a></nav>
    <nav aria-label="Footer"><a href="/privacy">Privacy</a></nav>
    
  3. 不要添加冗余角色,例如 <main role="main">。

验证:curl -sf https://example.com/ | grep -oE '(role|aria-[a-z]+)="' | sort -u

3.5 图片替代文本

当每个 <img> 都有 alt 属性时,即通过。没有图片的页面也通过。对于装饰性图片,alt="" 是正确的写法。

  1. 为每张内容图片编写简短描述。装饰性图片使用 alt="":
    <img src="team.jpg" alt="The Example Inc team at the 2026 offsite">
    <img src="divider.svg" alt="">
    

验证:curl -sf https://example.com/ | grep -oE '<img [^>]*>' | grep -vc 'alt='(预期结果为 0)

3.6 语言属性

当 <html> 带有有效的 BCP 47 代码(如 en、nl 或 en-US)作为 lang 属性时,即通过。

  1. 在根元素上设置语言:<html lang="en">。
  2. 在使用其他语言的元素上使用 lang:<blockquote lang="fr">。

验证:curl -sf https://example.com/ | grep -oE '<html[^>]* lang="[A-Za-z-]+"'

3.7 描述性链接文本

当抽查的链接不使用“点击此处”“阅读更多”“了解更多”“此处”“更多”“详情”或“信息”等通用文本时,即通过。

  1. 将通用文本替换为能说明链接目标的文本:
    <a href="/pricing">See the pricing plans</a>
    <a href="/blog/sprints" aria-label="Read the sprint planning guide">Read more</a>
    

验证:curl -sf https://example.com/ | grep -ciE '>(click here|read more|learn more|here|more)</a>'(预期结果为 0)

3.9 表单标签覆盖率

当每个可见表单字段都有标签时,即通过。标签可以是 <label for>、包裹字段的 <label>、aria-label、aria-labelledby、title 或 placeholder。没有字段的页面会跳过此项检查。

  1. 为每个字段关联一个标签:
    <label for="email">Email address</label>
    <input id="email" name="email" type="email">
    
  2. 尽可能使用可见的 <label>。仅使用 placeholder 作为标签的效果较弱。

验证:只读 shell 检查不会给出通过或失败的结果。请使用重新扫描命令。

3.10 表单字段自动填充

当 80% 或更多的文本、电子邮件、电话、URL、密码和搜索字段带有 autocomplete 属性时,即通过。达到 40% 或更多可获得部分分数。

  1. 为每个字段添加正确的令牌:
    <input name="name" autocomplete="name">
    <input name="email" type="email" autocomplete="email">
    <input name="phone" type="tel" autocomplete="tel">
    <input name="password" type="password" autocomplete="current-password">
    

验证:curl -sf https://example.com/ | grep -oE '<input[^>]*type="(text|email|tel|url|password)"[^>]*>' | grep -vc 'autocomplete='(预期结果为 0)

3.11 键盘可导航性

当页面没有正值 tabindex、没有缺少角色和焦点支持的可点击 <div>,也没有缺少角色的 <div> 或 <span> 事件处理器时,即通过。

  1. 移除正值 tabindex。使用 tabindex="0" 或自然顺序。
  2. 对可点击目标使用原生控件:
     <div onclick="openMenu()">Menu</div>
       <button type="button" onclick="openMenu()">Menu</button>
    

验证:curl -sf https://example.com/ | grep -cE 'tabindex="[1-9]'(预期结果为 0)

3.12 文档标题

当存在 <title>、标题并非通用名称(如“主页”“未命名”),且长度为 10 至 70 个字符时通过。

  1. 为每个页面设置唯一标题,包含页面主题和品牌:
    <title>Pricing plans for teams | Planner Pro</title>
    

验证:curl -sf https://example.com/ | grep -oE '<title>[^<]*</title>'

3.13 按钮的可访问名称

当每个 <button>、input 按钮和 [role="button"] 都通过文本、aria-label、aria-labelledby、title 或 value 获得名称时通过。

  1. 为图标按钮添加文本或 aria-label:
    <button type="button" aria-label="Close dialog"><svg aria-hidden="true">...</svg></button>
    <input type="submit" value="Send message">
    

验证:没有只读 shell 检查可以判定通过或失败。请使用重新扫描命令。

3.14 误用 aria-hidden

当 <body> 上没有 aria-hidden="true",且包含链接、按钮或输入框的容器上也没有该属性时通过。在 <body> 上使用 aria-hidden 会导致失败。

  1. 从 <body> 以及包含可聚焦元素的容器中移除 aria-hidden。
  2. 若要隐藏非活动内容,请使用 hidden 或 inert。这些属性也会移除焦点:
    <div id="old-panel" inert>...</div>
    

验证:curl -sf https://example.com/ | grep -c '<body[^>]*aria-hidden="true"'(预期为 0)

3.15 动态组件状态

适用于服务端 HTML 中包含组件或实时区域的情况。当每个组件都公开其状态,并且更新会被播报时通过。

  1. 公开披露控件、选项卡、切换控件和当前项的状态:
    <button aria-expanded="false" aria-controls="faq-1">Can I cancel?</button>
    <div id="faq-1" hidden>Yes, at any time.</div>
    
    <div role="tablist">
      <button role="tab" aria-selected="true" aria-controls="tab-1">Monthly</button>
    </div>
    <p role="status" aria-live="polite">3 results</p>
    
  2. 在更改视图的同一个脚本中更新 aria-expanded 和 aria-selected。

验证:curl -sf https://example.com/ | grep -oE 'aria-(expanded|selected|checked|pressed|current|live)=' | sort | uniq -c

常见陷阱

  1. 每个组件都会添加自己的 <h1>,导致页面上出现多个 <h1>。
  2. 没有 alt 的 <img src="..."> 会导致失败。用于装饰的图片使用 alt="" 是正确的。
  3. <div id="root"></div> 空壳没有可供 Agent 读取的文本。
  4. 如果模态框背景层包含模态框,在其上设置 aria-hidden="true" 会隐藏模态框。
  5. JavaScript 切换控件会更改视图,却不会更新 aria-expanded。

正确和错误示例请参阅 references/gotchas.md。

参考资料

评论

支持 Markdown