关于 aieo
aieo 是命令行工具,可检查网站构建产物、框架设置和部署配置中的 SEO 与 AI 搜索问题。它帮助网站开发者定位到源文件的问题,并依据已保存的基线判断变更是否引入问题。
主要功能
- 01检查构建产物与框架配置
- 02将问题定位到源文件
- 03与已保存的基线比较检查结果
- 04分析爬虫和 AI 引荐访问日志
- 05查看搜索表现和索引数据
- 06导出问题并通过 IndexNow 提交变更网址
适用场景
- 01在部署前通过 CI 捕获 SEO 缺陷
- 02查找网站变更引入的新问题
- 03调查爬虫拦截和 AI 搜索覆盖情况
- 04对照构建产物与搜索引擎索引
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
aieo-cli
在上线前检查网站的 构建产物的 SEO/GEO——aieo.ee 的内部视角。
aieo.ee 检查网站通过 HTTP 提供的内容。aieo 会读取构建生成的内容(dist/)、框架声明的内容以及部署配置添加的内容(_redirects、_headers、vercel.json、netlify.toml、Next.js 清单),并检查各部分是否相互一致:
站点地图 ↔ robots.txt ↔ 规范链接 ↔ hreflang ↔ 内部链接 ↔ llms.txt ↔ 重定向 ↔ 框架设置。有了基线后,它只会因本次更改导致的问题恶化而让构建失败。
aieo init # detect the framework, write aieo.toml
aieo check # check ./dist; exit 1 when the gate fails
aieo snapshot # save .aieo/baseline.json
aieo diff # fail only on findings new since the baseline
aieo export # .aieo/bundle.json.gz (aieo-bundle/v1) for aieo.ee
aieo rules / aieo explain C-SITEMAP-URL-NOINDEX
aieo logs ingest /var/log/nginx/ # crawler & AI-referral evidence from access logs
aieo logs report # coverage, verification, blocking, errors, AI referrals
aieo search google inspect # Google's view of the build's pages (URL Inspection)
aieo indexnow submit --yes # tell Bing & co. what changed since the baseline
aieo login && aieo push # upload the bundle to the aieo.ee project
aieo mcp # the same checks as read-only MCP tools for AI agents
安装
curl -fsSL https://raw.githubusercontent.com/web-casa/aieo-cli/main/scripts/install.sh | sh
每个 GitHub 版本发布页都附有适用于 Linux(x86_64、aarch64)、macOS(Apple 芯片、Intel)和 Windows 的静态二进制文件,每个文件旁还有一个 .sha256 文件;install.sh 会验证校验和,并安装到 ~/.local/bin(AIEO_VERSION=1.0.0 可固定版本,AIEO_INSTALL_DIR 可更改目录)。从源码安装:cargo install --git https://github.com/web-casa/aieo-cli aieo-cli(Rust 1.88+)。
框架
系统会根据 package.json 和配置文件检测预设(可通过 --preset 强制指定)。检测结果会标明页面对应的源文件。
| 预设 | 检查的构建产物 | 从配置中读取(仅字面值) | 可追溯到的页面 |
|---|---|---|---|
static | 任意目录 | — | — |
astro、starlight | dist/(outDir) | site、base、trailingSlash | src/pages/**、src/content/docs/** |
next | out/(output: 'export')或 .next/ | basePath、trailingSlash、output、metadataBase | app/**/page.*、pages/** |
nuxt | .output/public | site.url、app.baseURL、ssr、routeRules 重定向 | app/pages/**、pages/** |
vue | dist/(build.outDir) | base | src/pages/**(文件路由) |
tanstack | dist/client、.output/public、dist/ | base | src/routes/** |
hugo | public/(publishDir) | baseURL、uglyURLs、语言 | content/** |
vitepress | .vitepress/dist | sitemap.hostname、base、cleanUrls、srcDir | **/*.md |
docusaurus | build/ | url、baseUrl、trailingSlash | docs/**、blog/**、src/pages/** |
服务端构建(Next.js .next/、Nuxt 和 TanStack Start 的服务端 bundle)会按生产环境的方式提供:预渲染的 HTML、public/、routes-manifest.json 中的重定向/重写/标头,以及其他所有以 请求时渲染 的路由——指向这些路由的链接会被视为有效,但其 HTML 不会接受检查;若首页由服务端渲染,则首页模块会被标记为未经验证(除非使用 --allow-incomplete,否则退出码为 2)。对于客户端渲染的 SPA,会检查爬虫在不执行 JavaScript 时能看到的内容(K-SPA-SHELL)。fixtures/presets/ 中保存了每种框架下同一网站的真实构建产物及其快照(cargo test -p aieo-cli --test presets)。
检查内容
| 系列 | 示例 | |
|---|---|---|
| F01–F18 | aieo.ee 的 AI 就绪度模块,根据构建结果进行评估 | robots.txt AI 爬虫矩阵、noindex、站点地图、canonical、llms.txt、无需 JS 即可访问的内容 |
| P01–P04 | 多页面模块(GEOReady),覆盖每个可编入索引的页面,并单独按 0–100 评分 | 唯一的元数据、导航与实质内容、API / 产品数据、统一的组织身份 |
| T-… | 针对单个页面 | 缺少标题、标题重复(hreflang 替代页面除外)、JSON-LD 格式错误、JSON-LD 缺少 schema.org @context、缺少 Google 富媒体搜索结果所需属性、已停用的富媒体搜索结果类型(HowTo、FAQPage、…) |
| C-… | 覆盖整个构建 | 站点地图列出了缺失 / noindex / 非 canonical / 位于其他主机 / 被 robots.txt 屏蔽的页面;hreflang 缺少返回链接;canonical 指向缺失页面或其他主机;内部链接失效;孤立页面;llms.txt 链接指向缺失页面;生产环境发布了 Disallow: /;AI 搜索爬虫被屏蔽 |
| K-… | 配置 | 框架的 site / 基础路径 / 尾部斜杠设置与 canonical 和站点地图 URL 相矛盾;重定向循环、链和无效目标(含文件及行号);会对站点地图页面设置 noindex 的标头规则;静态导出时忽略 Next.js redirects();由一个客户端渲染外壳响应的路由 |
| L-… | 访问日志(aieo logs) | 爬虫被 WAF/CDN 屏蔽、爬虫请求返回 5xx、robots.txt 无法访问、部署后 404 激增、伪装爬虫、抓取被禁止的路径、AI 搜索覆盖率低 |
| S-… | 搜索引擎(aieo search) | 可编入索引的页面未被编入索引、Google 覆盖了 canonical、生产环境的响应与构建结果不同、点击量减半、IndexNow 密钥未提供 |
| D-… | 与基线对比 | 页面被移除但未设置重定向、页面被设为 noindex、canonical 已更改、hreflang 或结构化数据丢失、内容缩减 |
每条规则都有一个 ID、一个等级和一个来源:aieo rules、aieo explain <id>。
等级:error = 确定性缺陷(默认门禁不通过),
warning = 高风险(新增时会导致 diff 不通过),notice = 建议。没有官方来源的规则会标记为启发式规则,默认情况下绝不会判为错误;除非启用,否则基于长度的标题规则处于关闭状态。
退出码:0 门禁通过 · 1 门禁未通过 · 2 证据不完整
(没有首页、来源未知、HTML 无法解码)或用法错误 — 无法获取充分信息的检查绝不会报告“一切正常”。
与 aieo.ee 使用相同的规则
spec/ 中的规则元数据、爬虫目录和包架构由 @aieo/rules 导出,这是 aieo.ee 扫描器读取的包。F02–F18 有两套实现(aieo.ee 中使用 TypeScript,本项目中使用 Rust),并由 spec/fixtures/conformance 中的符合性测试用例保持一致:相同的微型站点、相同的模块状态、比率和原因(cargo test -p aieo-rules --test conformance)。F01(HTTPS、重定向)需要可访问的来源;F15 读取首页的 .md 对应文件,而不是使用内容协商。
访问日志
aieo logs ingest access.log access.log.1.gz # Nginx/Apache, Caddy, Cloudflare Logpush,
# Vercel drains, CloudFront — detected per file
aieo logs ingest app.log --format "nginx:\$host \$remote_addr [\$time_local] \"\$request\" \$status …"
CLOUDFLARE_API_TOKEN=… aieo logs pull cloudflare --zone <zone id> --since 7d
aieo logs report [--since 30d] [--format json]
aieo logs gaps --actor search_index # indexable pages AI search crawlers never fetched
aieo logs referrals # landing pages of visits from ChatGPT, Perplexity, …
- 对象:将用户代理与共享爬虫目录(
spec/crawlers.json:OAI-SearchBot、ChatGPT-User、GPTBot、Claude-*、PerplexityBot、Googlebot、Bingbot、Applebot 等)进行匹配,并分类为search_index、user_fetch、training、classic_search、其他自动化程序或真人。引荐来源(或utm_source)为 AI 答案平台的访问属于 AI 引荐。 - 是否已验证:通过爬虫运营方公布的 IP 范围检查其声明身份(下载后在
.aieo/cache/中缓存一天,并记录列表的creationTime),然后在运营方有相关文档说明时,通过正向确认的反向 DNS 进行检查。mismatch= 伪装;没有公布验证方法的爬虫标记为unverifiable,绝不称其为假冒。--offline会跳过网络检查。 - 本地保存:
.aieo/logs.db(SQLite)。根据文件的开头字节识别文件,因此不断增长的日志可以续读,轮换后的副本不会被重复计数。爬虫请求会保留加盐的 IP 哈希(.aieo/salt);真人访问只按天计数——不保存 IP 或浏览器用户代理。.aieo/.gitignore会将盐值、数据库和缓存排除在 git 之外。 - 发现项(L):爬虫收到的响应大多为 401/403/429(WAF / 机器人防护)、爬虫请求返回 5xx、robots.txt 无法访问(5xx/429)、爬虫请求的 404 激增、伪装爬虫、已验证爬虫访问了禁止路径、AI 搜索爬虫可访问的可编入索引页面很少。如果日志旁有构建结果,则会根据其中可编入索引的页面衡量覆盖率。
- Cloudflare GraphQL 会返回按小时抽样统计的计数,不含 IP:每行包含其计数,验证状态保持为
unchecked,并从区域的settings读取套餐限制。 - 如果
.aieo/logs.db存在,aieo export会在aieo-bundle/v1中添加日志汇总(logs)。
搜索引擎
所有操作都使用你自己的凭据,这些凭据保存在配置目录(~/.config/aieo/credentials.json,仅所有者可访问)中,或在 CI 中从环境变量读取。数据保存在 .aieo/search.db 中。
# Google Search Console — your own "Desktop app" OAuth client from Google Cloud
aieo search google login --client-secret client_secret.json # browser, loopback redirect
aieo search google pull --days 28 # clicks per page and day, top queries
aieo search google inspect [--limit 200] # URL Inspection of indexable pages, stalest first
# Bing Webmaster Tools — API key from Settings → API Access
aieo search bing key # or BING_WEBMASTER_API_KEY
aieo search bing pull
aieo search bing import-ai export.csv # AI Performance overview export (Date, Citations, Cited Pages)
aieo search report
- CI:将
GOOGLE_APPLICATION_CREDENTIALS设置为服务账号密钥,其电子邮件必须是 Search Console 资源的用户(设备授权流程不允许使用 Search Console 作用域)。 - URL Inspection 会在本地记录配额使用情况(每个资源每天 2,000 次,每分钟 600 次),并优先检查最久未检查的 URL。
- 发现项(S),对照构建结果读取:可编入索引但 Google 尚未编入索引的页面;被 Google 替换规范网址的页面;构建结果提供、但 Google 无法抓取/发现被屏蔽/发现
noindexed的页面(生产环境与构建结果不一致);点击量较上一时段减半;构建结果未提供的 IndexNow 密钥。 - Bing 的 AI Performance 和 Google 的 AI Overviews 报告没有 API;Bing 概览导出文件按与 aieo.ee 相同的规则导入。
IndexNow
aieo indexnow keygen --write # key file into public/ (static/ for Hugo, Docusaurus)
aieo indexnow verify # in the build? served live?
aieo indexnow submit # plan: new, changed and removed pages since the baseline
aieo indexnow submit --yes # send (Bing, Yandex, Seznam, Naver, … share it; not Google)
通过将页面哈希与基线(aieo snapshot)进行比较来查找变更,因此只发送部署所修改的内容。未指定 --yes 时不会发送任何内容,每个请求都会记录在 .aieo/audit.jsonl 中。
aieo.ee
aieo login # an organisation API key with write access; finds the project for `site`
aieo push # export the bundle (check + logs + search) and upload it
aieo push 会将数据上传到 aieo.toml 中的 [aieo] project(或使用 --to <id>)。相同提交和类型的重复上传会被识别为同一次运行。数据包包含发现项、页面清单和汇总数据——不包含页面源代码、原始日志或 IP 地址;也可以将其拖放到项目的 “Inside view” 页面。
配置(aieo.toml)
site = "https://example.com" # production origin
dist = "dist"
preset = "starlight"
[check]
# fail_on = ["error"] # default; with a baseline ["new:error", "new:warning"]
baseline = ".aieo/baseline.json"
ignore = ["/drafts/**"] # URL paths left out of page rules
[rules]
"C-ORPHAN-PAGE" = "notice" # error | warning | notice | off | on
[[suppress]] # every suppression has an owner, a reason and an expiry
rule = "C-LINK-BROKEN"
url = "/legacy/**"
reason = "old docs, removed in Q1"
owner = "docs-team"
expires = "2026-12-31"
[aieo]
project = "…" # aieo.ee project id for `aieo push`
[search]
google_property = "sc-domain:example.com" # default: the property covering `site`
bing_site = "https://example.com/"
[indexnow]
key = "…" # public; served as /<key>.txt
[[hosting.rewrites]] # routing the build cannot show (middleware, edge functions)
from = "/:path*"
to = "/en/:path*"
[[hosting.redirects]]
from = "/old/:slug"
to = "/new/:slug"
status = 301
[[hosting.*]] 规则会在构建配置和主机配置声明的规则之后应用;如果路由逻辑位于代码中(Next.js 中间件、边缘函数),请使用这些规则,以免指向重写路径的链接被报告为失效。
CI
- run: npm run build
- uses: web-casa/aieo-cli@v1 # composite action, see action.yml
with:
version: 1.3.0 # prebuilt binary; the default "source" builds with cargo
command: diff # or check
upload-sarif: "true" # GitHub code scanning (security-events: write)
# push: "true" # upload the bundle to aieo.ee (aieo-api-key: ${{ secrets.AIEO_API_KEY }})
# indexnow: "true" # submit what changed since the baseline
发现会以注释的形式显示在拉取请求中,作业摘要中会添加 Markdown 摘要,SARIF 和证据包会写入项目目录旁边。不使用此操作时:
aieo diff --format github --report sarif=aieo.sarif --report bundle=.aieo/bundle.json.gz。
GitLab:引入 ci/gitlab-ci.yml 并扩展 .aieo;发现会以 JUnit 测试报告的形式显示在合并请求中。
AI Agent(插件、技能、MCP)
aieo 二进制文件必须位于 PATH 中(参见安装)。然后:
| Agent | 安装 |
|---|---|
| Claude Code | /plugin marketplace add web-casa/aieo-cli,然后运行 /plugin install aieo@aieo |
| Codex | codex plugin marketplace add web-casa/aieo-cli,然后运行 codex plugin add aieo@aieo |
| 支持技能的任意 Agent(OpenClaw、Hermes、Cursor 等) | npx skills add web-casa/aieo-cli |
| Claude Desktop 和其他 MCPB 宿主 | 打开来自发布页的 aieo-v<version>.mcpb,并选择网站目录 |
| 任意 MCP 客户端 | {"command": "aieo", "args": ["mcp"]},在项目目录中启动 |
同一目录也是一个 Cursor 插件(.cursor-plugin/),可用于 Cursor Marketplace;在其上架之前,请使用上面的技能和 MCP 条目。
该插件包含五项技能——aieo(检查 → 编辑源文件 → 重新构建 → 检查)、aieo-ci、aieo-crawlers、aieo-indexing、aieo-llms-txt(plugins/aieo/skills)——以及 MCP 服务。
aieo mcp 通过 stdio 提供只读工具:check、diff、page、explain_rule、list_rules、logs_report、logs_gaps、search_report、indexnow_plan、push_plan。每个工具都可选接受 project(相对于服务运行位置的目录),用于单体仓库中的一个网站。不会有任何工具向本机以外的位置写入数据——*_plan 工具会展示 aieo indexnow submit --yes 或 aieo push 将执行的操作,供用户运行。
输出和数据
--format pretty | json | sarif | github | markdown | junit,以及任意数量的 --report FORMAT=PATH(bundle = gzip JSON)。JSON 和证据包采用 aieo-bundle/v1(spec/bundle.schema.json):包含发现、页面清单、就绪度和多页面评分——绝不包含页面源代码、原始日志或 IP 地址。配置类发现会附带配置文件和行号(astro.config.mjs:4、vercel.json:12),因此 SARIF 和 GitHub 注释会指向需要更改的设置。
规则版本
规则来自 @aieo/rules(嵌入在二进制文件中):补丁版本会更改措辞或修复误报,小版本会添加规则,大版本会更改现有规则的含义。规则 ID 永不复用。基线创建后新增或扩大适用范围的规则(参见 spec/rules-history.json 中的 changed)所产生的发现会报告为 unknown,而非 new,因此仅升级 aieo 不会导致 aieo diff 失败;请创建新快照以纳入该规则。
开发
cargo test --workspace
cargo clippy --workspace --all-targets -- -D warnings
# refresh spec/ from aieo.ee's @aieo/rules (in the aieo-v5 monorepo)
pnpm --filter @aieo/rules export:cli <path to this repo>
Crates:aieo-core(规范、发现、配置、证据包)· aieo-site(生产环境实际提供服务的构建目录:路由、主机规则、robots、站点地图、HTML、框架预设)· aieo-rules(F / P / T / C / K / D)· aieo-report(格式)· aieo-logs(解析器、分类、IP 验证、SQLite 存储、Cloudflare GraphQL)· aieo-search(Search Console、Bing Webmaster、IndexNow、凭据、aieo.ee 上传)· aieo-cli(aieo 二进制文件)。
采用 MIT 许可证。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。