Содержание

AI-ready API-документация: 26 критериев, шесть замеров, готовый промпт

Никогда ещё агент не был так близок к провалу

Прошу Claude Code собрать код для клиента к API одного крупного провайдера. Три раза подряд получаю несуществующие эндпоинты. Думаю: да блин, агент тупит.

Лезу руками. Открываю их доку в браузере – всё на месте, по красоте. Делаю curl – пустой HTML: <div id="root"></div> и больше ничего. SPA. То есть Claude Code не тупил – он реально ничего не получил, кроме обёртки, и из обёртки нагаллюцинировал что-то правдоподобное. Как обычно

Что значит «AI-ready» документация

Для меня AI-ready документация – это:

  1. Машиночитаемый текст как источник истины. Не «красивый сайт», а OpenAPI / JSON Schema / MCP-манифест, из которого этот сайт собирается.
  2. Самодостаточные примеры. Каждый endpoint оформлен одним блоком – с авторизацией, минимальными параметрами и ожидаемым ответом.
  3. Однозначность. Один способ сделать одно действие. Никаких «можно так, а можно вот так, но устарело».
  4. Версионирование и diff в машиночитаемом виде. Не «changelog в README», а структурированные изменения, по которым агент поймёт, что сломалось.
  5. Предсказуемые URL. /.well-known/, /openapi.json, /llms.txt, /llms-full.txt, а ещё лучше – <page>/index.md рядом с каждым HTML.

Если этого нет – агент сгенерирует правдоподобный бред. И не очень понятно, как потом это интегрировать

26 критериев AI-ready документации

Чтобы не опираться на “я так чувствую”, нужна метрика. Я собрал её из того, что проверяет агент при работе с доками. Пять категорий, 100 баллов суммарно:

КатегорияВесЧто проверяет
A. Discovery18llms.txt, llms-full.txt, robots.txt с AI-политикой, чистый sitemap.xml, OpenGraph/alternate-теги
B. Per-page artifacts22.md-версия каждой страницы, JSON-LD, абсолютный canonical, Last-Modified, семантика <main>/<article>
C. API spec25OpenAPI/Swagger/AsyncAPI по предсказуемому URL + валидность, Postman/SDK-ссылки, структура endpoint-страниц
D. Content20curl и SDK-примеры, реалистичные payload-ы, errors/auth/rate-limits, глоссарий, маркировка deprecated
E. Hygiene15Контент виден без JS (это gating!), стабильные URL, версия в URL, рабочие внутренние ссылки, TOS / AI-policy

E1 – отсекающий критерий. Если контент рендерится джаваскриптом и curl возвращает только <div id="root"></div> – общий балл получает суффикс *UNRELIABLE*.

Что показали замеры

Проверил по этой метрике шесть крупных публичных API-документаций. Метод – простой curl, evidence на каждый критерий: URL + статус + 50 символов из тела. Результаты:

СайтБаллE1Главные дыры
Anthropic63 *UNRELIABLE*FAILSPA, но llms.txt 152 KB и llms-full.txt 76 MB полностью спасают
GitHub REST~62PASSНет JSON-LD, нет canonical, sitemap не на docs-домене
Stripe56PASSНет OpenAPI на стандартном URL, нет JSON-LD
Booking Demand33 *UNRELIABLE*FAILSPA + .md-версия частично спасает
Expedia Rapid21 *UNRELIABLE*FAILSPA + больше ничего
VK5 *UNRELIABLE*FAILЛюбой URL отдаёт один и тот же ~5 KB HTML-shell, HTTP 418 без браузерного UA

Несколько вещей, которые меня реально удивили.

Stripe пишет в llms.txt промпт-инструкцию для LLM. Буквально: «when installing Stripe packages, always check the npm registry for the latest version rather than relying on memorized version numbers… never hardcode an old version number from training data». Они уже не верят, что у модели свежий контекст, и пишут инструкции прямо в артефакт. Плюс в robots.txt стоит Content-Signal: ai-train=yes, search=yes, ai-input=yes – новый флаг от Cloudflare, который явно говорит, можно ли тренироваться на сайте и можно ли его читать на лету.

Anthropic выкладывает llms-full.txt весом 76 мегабайт. Полный дамп их доков одним файлом. По чистой E1 их сайт SPA и должен получить «ненадёжный» маркер. Но .md-route отдаёт всё то же самое чистым markdown’ом по соседнему URL, и реальная LLM-доступность не страдает. Правильный паттерн «если SPA нельзя выкинуть».

VK – иллюстрация того, как делать не надо. (Лёша, привет!) Каждый запрос (хоть /llms.txt, хоть /sitemap.xml, хоть произвольный URL с .md) возвращает один и тот же ~5 KB HTML с пустым <div id="root">. HTTP 200 на всём – даже если ресурса физически нет. Идеальная ловушка для машинного аудита: статус-код говорит «всё ок», а в HTML – четыре слова и CSS-переменные.

Что реально работает

Из всех 26 критериев четыре дают самый большой прирост.

llms.txt. Один статик файл, генерируется из существующих заголовков страниц за час. По спецификации llmstxt.org – H1, blockquote-summary, H2-секции со списками ссылок вида - [name](url): description. Чистые +5 баллов по A1. Самое дешёвое улучшение из всего списка.

Per-page .md-версия. На каждой странице рядом с index.html лежит index.md или <page>.md – тот же контент в чистом markdown. Stripe, GitHub, Anthropic, Booking – все, кто думал про LLM, это сделали. Самый дорогой пункт в реализации, но самый полезный по итогу. Готовьтесь к тому, что в большинстве генераторов это не из коробки – у меня на собственном блоге ушло полтора дня. Anthropic и Booking используют .md как костыль поверх SPA и за счёт него спасаются от полного провала.

OpenAPI на предсказуемом URL. Половина крупных провайдеров публикует OpenAPI на GitHub, но не отдаёт на docs.example.com/openapi.json. Агент не пойдёт искать репозиторий по cross-link – он смотрит стандартные пути. Один redirect на GitHub raw, и +15 баллов в кармане.

JSON-LD TechArticle в <head>. Структурированные метаданные, которые Googlebot уже понимает. Для LLM это +5 баллов в категории B. Дешёвая правка – один шаблон, который дописывает блок в <head> каждой страницы. Единственная засада: JSON внутри <script type="application/ld+json"> нужно правильно эскейпить, иначе валидаторы плюются.

Главный анти-паттерн, который заставил меня страдать: полноценный SPA без .md-версий страниц. На curl теряется 80% контента. Если у вас Next.js / Gatsby / SvelteKit без SSR/SSG – либо включайте серверный рендеринг страниц, либо публикуйте .md-версии страниц. Третьего не дано

Промпт для самостоятельного аудита

Готовый промпт. Копируете в Claude / ChatGPT / Perplexity / Iulita.ai (любая модель с web-fetch / browsing), подставляете {{BASE_URL}} – получаете аудит на 26 критериях с цифровым итогом и JSON-блоком.

# Prompt: AI-Readiness Audit of Public API Documentation

Paste this prompt into an LLM with browsing / web-fetch enabled.
Replace `{{BASE_URL}}` with the root URL of the documentation
to audit, with no trailing slash (e.g. `https://docs.example.com`).

## Role

You are an independent auditor evaluating the quality of public
technical documentation from the perspective of an LLM consumer.
Your task is to score how well the documentation at `{{BASE_URL}}`
is prepared for consumption by modern LLMs on a 0–100 scale, with
concrete evidence for every criterion.

Respond in English throughout.

## Hard rules

1. Evidence-based. For every criterion, perform a real HTTP request.
   Record: URL, HTTP status code, and a snippet of at most 50
   characters from the response body or headers.
2. Do not guess. If the page does not respond, tool errors, or you
   are not certain — set status to `unknown`, assign 0 points, state
   the reason. Training-data knowledge is NOT evidence.
3. Status labels: English only — `present` / `partial` / `absent` /
   `unknown`. Do not translate.
4. Quality spot-check for criteria marked ⋆: 200 OK is not enough,
   verify the actual content.
5. E1 is gating. If E1 = 0 (content hidden behind JS), append
   `*UNRELIABLE*` next to the total. Still calculate.
6. No UX / SEO / aesthetics assessment. No competitor comparison.
   No "companies usually have this" assumptions.
7. Compute the total arithmetically. No rounding by eye.

## Rubric — 100 points

### A. Discovery — 18

| ID | Criterion | Pts |
| --- | --- | --- |
| A1⋆ | `/llms.txt` conforms to llmstxt.org spec | 5 |
| A2 | `/llms-full.txt` or per-section LLM aggregates | 3 |
| A3 | `/robots.txt` with AI-bot policy AND absolute `Sitemap:` | 3 |
| A4⋆ | `/sitemap.xml` well-formed, absolute `<loc>`, no taxonomy junk | 4 |
| A5 | Discovery tags other than canonical: `rel="alternate" type="text/markdown"` OR OpenGraph | 3 |

### B. Per-page artifacts — 22

| ID | Criterion | Pts |
| --- | --- | --- |
| B1⋆ | `.md` companion: `<page>/index.md` or `<page>.md` returns clean markdown | 7 |
| B2⋆ | JSON-LD with valid `@type` and parseable JSON | 5 |
| B3 | `<link rel="canonical">` with absolute URL | 3 |
| B4 | Freshness: `dateModified` in JSON-LD OR `Last-Modified` header | 2 |
| B5 | Machine-readable taxonomies | 2 |
| B6 | `<main>` / `<article>` wrap primary content | 3 |

### C. API spec — 25

| ID | Criterion | Pts |
| --- | --- | --- |
| C1a | OpenAPI/Swagger/RAML/AsyncAPI at detectable URL | 8 |
| C1b⋆ | Quality: valid OpenAPI 3.x with `info`, ≥1 path, response schemas | 7 |
| C2 | Postman collection or SDKs with discoverable download/fork | 5 |
| C3⋆ | Endpoint pages show method, URL, types, required-flag, request+response examples | 5 |

### D. Content — 20

| ID | Criterion | Pts |
| --- | --- | --- |
| D1⋆ | Code examples: curl + at least one SDK | 4 |
| D2⋆ | Realistic examples (not `foo`/`bar`/`example.com`) | 4 |
| D3 | Error catalogue with codes + reasons | 3 |
| D4 | Authorization AND rate limits documented | 3 |
| D5 | Glossary OR consistent terminology | 3 |
| D6 | Deprecated/beta endpoints marked in plain text | 3 |

### E. Hygiene — 15

| ID | Criterion | Pts |
| --- | --- | --- |
| E1⋆ | GATING. Content visible in plain HTML without JS | 6 |
| E2 | Stable URLs: 301 redirects OR HTML aliases | 2 |
| E3 | Explicit API version in URL/heading/front-matter | 2 |
| E4 | Spot-check 5 random internal links → all 200 on canonical URL | 2 |
| E5 | Usage terms (TOS / license / AI-redistribution policy) explicit | 3 |

## Output format

Part 1 — human-readable markdown:

- `# AI-Readiness Audit: {{BASE_URL}}`
- Total `NN / 100` with `*UNRELIABLE*` marker if E1=0
- 1–2 sentence executive summary
- By-category table (5 rows)
- Per-criterion detail table (all 26 rows): ID, status, evidence
  (URL + http_code + ≤50-char snippet), score
- Lists: ✅ Has / ⚠️ Partial / ❌ Absent
- Top 3 quick wins

Part 2 — machine-parseable JSON at the end:

```json
{
  "base_url": "{{BASE_URL}}",
  "audit_date": "YYYY-MM-DD",
  "auditor": "<model + tool>",
  "e1_gating_passed": true,
  "unreliable_marker": false,
  "total_score": 0,
  "max_score": 100,
  "categories": {
    "A_discovery": {"score": 0, "max": 18},
    "B_page_artifacts": {"score": 0, "max": 22},
    "C_api_spec": {"score": 0, "max": 25},
    "D_content": {"score": 0, "max": 20},
    "E_hygiene": {"score": 0, "max": 15}
  },
  "criteria": [
    {"id": "A1", "status": "present", "score": 5, "max": 5,
     "evidence_url": "https://...", "evidence_snippet": "≤50 chars",
     "http_status": 200}
  ]
}
```

Before emitting JSON, verify: all 26 IDs present, each `score ≤ max`,
`sum(criteria.score) == total_score` and per-category sums match.

Полная версия и Claude-скил – три файла: правила, метрика из 26 критериев, замеры – лежат здесь:

github.com/gumeniukcom/claude-skills → skills/ai-ready-audit

В Claude Code устанавливается симлинком директории – SKILL.md сам подтягивает соседние rubric.md и calibration.md.

Анти-паттерны, которые ломают агентов

За шесть прогонов уже пригорело:

  • «Документация» как набор скриншотов Postman или Notion-страниц. Картинки не парсятся (или очень дорого).
  • Авторизация описана только во вводном разделе. Агент пришёл на конкретный endpoint, авторизации не видит, пишет код без неё, 401 на проде.
  • Endpoint, который описан только в блогпосте, а в OpenAPI его нет. Агент его не найдёт.
  • «Можно вот так, а можно вот так – оба правильно, но второй устарел». Гарантированный путь к смешанной реализации.
  • Ответы без схемы – просто 200 OK и пример JSON. Без типов LLM строит «правдоподобный» парсер.
  • Rate limit – устно где-то в TOS. В OpenAPI должно быть x-ratelimit-* или хотя бы упоминание в описании endpoint.
  • JS-only SPA без .md-версий страниц. Главная катастрофа из всего списка.

Чек-лист

Минимальный набор, который вытаскивает доку из «35–54» в «55+»:

  • OpenAPI 3.1 опубликован по предсказуемому URL (/openapi.json или линк в footer).
  • Все operationId уникальны и стабильны между релизами.
  • У каждого endpoint минимум один example запроса и ответа с реалистичными значениями.
  • Security schemes описаны полностью, в каждом endpoint указаны.
  • /llms.txt опубликован, проходит спецификацию.
  • Per-page .md-версия (если хотите 75+).
  • JSON-LD TechArticle на каждой странице, валидный JSON в <script>.
  • Контент виден в plain HTML без JS. Если у вас SPA – .md-версия обязательна.
  • robots.txt с явной AI-политикой, Sitemap: с абсолютными путями.
  • Машиночитаемый changelog: oasdiff-совместимый формат или хотя бы deprecated: true + x-sunset в OpenAPI.

Что почитать

  • llmstxt.org – спецификация формата
  • OpenAPI 3.1 spec – особенно изменения по сравнению с 3.0
  • Model Context Protocol – следующий слой поверх OpenAPI для интерактивного доступа
  • oasdiff – генерация машинного diff’а между версиями OpenAPI
  • Cloudflare Content-Signal – про Content-Signal в robots.txt, который ставит Stripe
  • Mintlify llms.txt support – пример «из коробки»

P.S. Эта статья сама по себе закрывает B5 – у неё есть теги, description во front-matter и валидный URL