AEO

llms.txt — kompletny przewodnik 2026 (spec + kod)

llms.txt to standard dla AI crawlers (ChatGPT, Claude, Perplexity). Spec llmstxt.org, przykłady z yote.pl, generowanie dynamic, licensing RSL 1.0.

Wiktor Śmiech · · 12 min czytania · aktualizacja:
Wiktor Śmiech

Wiktor Śmiech

Web Engineer

12 lat web engineering, w tym 5 lat w software house przed freelance. 50+ zbudowanych stron, 20+ sklepów dla klientów z UK, USA i Polski. Stack: Astro, Next.js, React, WordPress, WooCommerce. Specjalizuje się w Core Web Vitals, architekturze SEO i integracjach e-commerce.

AstroNext.jsReactWordPress

llms.txt — co to jest i po co

llms.txt to plaintext file umieszczony w root domenie (przykład: https://yote.pl/llms.txt) służący jako struktura nawigacyjna dla AI crawlers (ChatGPT, Claude, Perplexity, Gemini). Analogicznie do robots.txt (regulating access) i sitemap.xml (lista URLs), llms.txt dostarcza zoptymalizowaną pod AI reprezentację strony: H1 z nazwą, blockquote z summary, sekcje H2 z linkami i krótkimi opisami. Spec: llmstxt.org (wrzesień 2024). Format: Markdown plain text. Wsparcie 2026: Anthropic ClaudeBot (oficjalnie), Perplexity (częściowo), OpenAI GPTBot (odczyt w beta). Korzyści: szybsza indeksacja, niższe token costs dla AI, lepsza citation quality.

Spec został zaproponowany przez Jeremy’ego Howarda (fast.ai, Answer.AI) 3 września 2024 i w ciągu pół roku zyskał traction wystarczający, żeby pojawić się w oficjalnych dokumentacjach Anthropic i Mintlify. Do kwietnia 2026 plik implementuje około 2% top 1000 domen globalnie — to mało, ale trend rośnie kwartalnie. Dla nowej strony dodanie llms.txt to koszt 30 minut pracy, który może dać przewagę na 3-5 lat do przodu.

Terminologia AEO (Answer Engine Optimization), GEO (Generative Engine Optimization), entity clarity, citation rate — zebrana w jednym miejscu w Słowniku SEO 2026 (50 terminów z definicjami i przykładami).

Czym różni się od robots.txt i sitemap.xml

PlikCelFormatAudience
robots.txtAllow / Disallow crawlersDirectivesWszystkie crawlery
sitemap.xmlLista wszystkich URLsXMLSearch engines
llms.txtSemantic map dla AIMarkdownAI answer engines

Kluczowe różnice:

  • robots.txt — NIE zawiera semantic context, tylko access rules (User-agent: GPTBot / Allow: /). Mówi „wolno wchodzić”, ale nie mówi „to jest ważne, a tamto mniej”.
  • sitemap.xml — zawiera URLs w formie listy (z lastmod, priority), ale bez hierarchii i opisów. Dla crawlera klasycznego wystarczy — dla AI, które próbuje zrozumieć entity, to ubogie źródło.
  • llms.txt — zawiera „here’s what’s important, grouped, with context”. Idealne dla AI, które muszą szybko zrozumieć stronę bez parsowania 100 HTMLi z nawigacją, stopką, popupami cookie i reklamami.

Analogia: robots.txt to tabliczka „wstęp wzbroniony / wolno wejść” na drzwiach. sitemap.xml to spis treści książki. llms.txt to streszczenie dla czytelnika, który ma 5 minut i musi zrozumieć o co chodzi.

Spec llmstxt.org — wymagane elementy

Format jest celowo minimalistyczny. Zero konfiguracji, zero frontmatter YAML, zero XML. Czysty Markdown z czterema regułami:

  1. H1 (pojedynczy) — nazwa projektu lub strony: # Inspirax
  2. Blockquote summary — 1-2 zdania opisu: > Agencja SEO i web development z Buska-Zdroju
  3. Optional paragraf — dodatkowy kontekst (co robicie, jak się zgłosić, jaka data aktualizacji)
  4. H2 sekcje — kategorie, każda z listą [Link title](URL): opis

Opcjonalne rozszerzenia:

  • llms-full.txt — rozszerzona wersja z pełnymi opisami (gdy core llms.txt przekracza ~10 000 znaków, spec rekomenduje split)
  • RSL 1.0 licensing header (2025 proposal dla deklaracji praw AI training)
  • Sekcja z kontaktem i danymi firmy (NIP, REGON, godziny)

Dobre praktyki produkcyjne:

  • Plain text, bez CSS/JS, bez osadzanych obrazków (tylko linki)
  • Pod 10 000 znaków dla llms.txt core (większość stron mieści się w 2-3k znakach)
  • Prawidłowa hierarchia: H1 → H2 (maksimum). H3 nie używamy — spec jest płaski.
  • Explicit kontakt — email, telefon, adres
  • Last updated date w paragrafie wstępnym (ułatwia AI ocenę świeżości)

Przykład minimalny:

# Example Company
> Short 1-2 sentence company description.
Additional context about what we do and how to contact us.
Last updated: 2026-04-18.
## Services
- [Service A](/services/a): Description of service A
- [Service B](/services/b): Description of service B
## Blog
- [Recent Post Title](/blog/post-slug): Short post summary

Tyle. Bez skomplikowanych schematów, bez walidatorów — jedyny „walidator” to sprawdzenie, czy AI odpowiada na zapytania o Twoją stronę przy użyciu tych samych linków i opisów, które tu podasz.

Dlaczego llms.txt teraz — argumenty techniczne

1. Token economy w AI crawlers

AI crawlery mają budżet tokenowy na każdą odwiedzoną domenę. Scraping strony firmowej (homepage + 10 subpages HTML z nawigacją, sidebar, footer, cookie popupami) to około 50 000 tokenów wejściowych. Ta sama strona zreprezentowana w llms.txt to około 1 500 tokenów33x tańsza indeksacja.

Z perspektywy OpenAI/Anthropic: kiedy budget crawla się wyczerpie, Twoja strona NIE zostanie w pełni zindeksowana. llms.txt to sygnał „tu masz skondensowaną wersję, wykorzystaj budget mądrze”.

2. Citation quality — AI cytuje to co rozumie

Jeśli AI musi zgadywać co jest najważniejsze na stronie, może zacytować copy z footera, disclaimer cookie albo tekst przyciemniony w CTA. llms.txt to explicit sygnał „tak ta strona ma być zrozumiana” — co daje poprawniejsze cytowania z czystym atrybutem.

W praktyce: jeśli blogpost ma się wyświetlać w Perplexity jako źródło, warto umieścić go w sekcji ## Blog llms.txt z jednozdaniowym opisem. Perplexity przetwarza llms.txt podczas crawl-on-demand i używa opisów jako preview snippets.

3. Brand control

Ty decydujesz co AI widzi jako „core” Twojej strony. Jeśli masz stronę z architekturą dla ludzi (duże banery, grafika Framer, animacje), AI parsing HTML może zgubić prawdziwą treść w szumie DOM-u. llms.txt = Twoja kuratorska wersja strony. Bez elementów UI, bez powtarzalnego layoutu, bez marketingowego fluff.

4. Prognoza adoption

Kwiecień 2026: około 2% top 1000 domen globalnie ma llms.txt. Anthropic, Mintlify, Vercel, Zapier, Hugging Face — wszyscy implementują. Prognoza 2028: 30-50% top 10 000. Dla nowej strony wdrożenie teraz to pozycja early-mover przy zerowym koszcie technicznym.

Implementacja static — prosta droga

Najprostsza ścieżka (dla stron do 20 podstron):

  1. Utworzyć plik public/llms.txt
  2. Wypełnić zgodnie ze spec
  3. Commit + deploy

Po deploy plik jest dostępny pod https://twojadomena.pl/llms.txt — bez żadnej konfiguracji serwera, bez MIME type fights (większość hostingów serwuje .txt jako text/plain domyślnie).

Przykład produkcyjny dla agencji usługowej:

# Inspirax
> Agencja SEO i web development z Buska-Zdroju — Kielce i świętokrzyskie.
Inspirax buduje strony firmowe i sklepy internetowe zoptymalizowane pod SEO,
AEO (AI answer engines) i CRO. Działamy dla firm z Kielc, Buska-Zdroju,
Starachowic, Ostrowca Świętokrzyskiego. Last updated: 2026-04-18.
- Strona główna: https://yote.pl/
- Blog: https://yote.pl/blog
- Kontakt: kontakt@inspirax.pl, +48 579 522 171
## Usługi
- [Pozycjonowanie SEO](https://yote.pl/uslugi/pozycjonowanie): Pakiety Local 1 900 zł/mies, Standard 3 900 zł, Premium 7 900 zł.
- [Strony internetowe](https://yote.pl/uslugi/strony-internetowe): od 6 900 zł (Starter) do 29 900 zł (custom z architekturą SEO).
- [Audyt SEO](https://yote.pl/uslugi/audyt-seo): 4 900 zł pełny audyt techniczny, darmowy audyt wstępny.
- [AI Search / AEO](https://yote.pl/uslugi/aeo): Optymalizacja pod ChatGPT, Perplexity, Gemini. Audyt AEO 2 900 zł, AEO Boost +1 500 zł/mies.
## Blog
- [Ile kosztuje strona internetowa w 2026](https://yote.pl/blog/ile-kosztuje-strona-internetowa): Cennik stron od 6 900 zł. Firmowa vs SEO vs sklep.
- [llms.txt — kompletny przewodnik](https://yote.pl/blog/llms-txt-przewodnik-2026): Spec, przykłady, kod dynamic endpoint w Astro.
## Zespół
- Bartosz — SEO, CRO, AEO, 4 lata.
- Wiktor Śmiech — Web Engineer, 12 lat, 50+ stron, 20+ sklepów.
## Dane firmy
- Nazwa prawna: Wiktor Śmiech Inspirax
- NIP: 6551984596
- REGON: 522874232
- Adres: ul. Kościuszki 15a, 28-100 Busko-Zdrój

To wystarczy dla 80% stron w internecie. Jeśli masz statyczną agencję z 5-10 usługami i 20 blogpostami — zostaw na tym. Update raz na kwartał kiedy zmieniasz cennik.

Implementacja dynamic — Astro + Content Collections

Problem wersji static: ręcznie utrzymujesz i synchronizujesz z blog / uslugi / portfolio. Przy dodaniu 15 blogpost-a zapomnisz update’ować llms.txt. Po roku plik jest desynchronizowany z realną stroną.

Rozwiązanie: dynamic endpoint który generuje llms.txt z Astro content collections przy build.

Poniżej kod produkcyjny z yote.pl/llms.txt (ścieżka w repo: src/pages/llms.txt.ts):

export const prerender = true;
import { getCollection } from 'astro:content';
import type { APIRoute } from 'astro';
/**
* Dynamic /llms.txt endpoint — auto-generates an up-to-date llms.txt
* from content collections at build time.
*
* Spec: https://llmstxt.org
*/
export const GET: APIRoute = async ({ site }) => {
if (!site) {
throw new Error('`site` must be configured in astro.config.mjs');
}
const base = site.toString().endsWith('/') ? site.toString() : `${site.toString()}/`;
// Load collections (exclude drafts)
const [uslugi, portfolio, blog] = await Promise.all([
getCollection('uslugi', ({ data }) => !data.draft),
getCollection('portfolio', ({ data }) => !data.draft),
getCollection('blog', ({ data }) => !data.draft),
]);
// Sort by order / date
const uslugiSorted = [...uslugi].sort(
(a, b) => (a.data.order ?? 0) - (b.data.order ?? 0),
);
const blogSorted = [...blog].sort(
(a, b) => new Date(b.data.date).getTime() - new Date(a.data.date).getTime(),
);
const lines: string[] = [];
lines.push('# Inspirax');
lines.push('> Agencja SEO i web development z Buska-Zdroju — Kielce i świętokrzyskie');
lines.push('');
lines.push(`- Strona główna: ${base}`);
lines.push(`- Kontakt: kontakt@inspirax.pl, +48 579 522 171`);
lines.push('');
// Usługi
lines.push('## Usługi');
for (const u of uslugiSorted) {
const desc = u.data.ai_summary ?? u.data.description;
const price = u.data.price_from ? ` (${u.data.price_from})` : '';
lines.push(`- [${u.data.title}](${base}uslugi/${u.id}): ${desc}${price}`);
}
lines.push('');
// Blog
lines.push('## Blog');
for (const post of blogSorted) {
const desc = post.data.ai_summary ?? post.data.description;
lines.push(`- [${post.data.title}](${base}blog/${post.id}): ${desc}`);
}
lines.push('');
return new Response(lines.join('\n'), {
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
});
};

Co to robi:

  • export const prerender = true — generuje plik przy build, nie runtime (zero cold start overhead)
  • getCollection('uslugi', ({ data }) => !data.draft) — type-safe filter po frontmatter
  • new Response(...) + Content-Type: text/plain — poprawny MIME dla AI crawlerów

Zalety wersji dynamic:

  • Pojedynczy edit MDX → auto-update llms.txt przy kolejnym build
  • TypeScript type safety (frontmatter schema validation w content.config.ts)
  • Zero ręcznej synchronizacji między content a llms.txt
  • Przy migracji (rename URL-a, dodanie sekcji) — zmieniasz w content config, llms.txt podąża

Alternatywa dla WordPress: plugin „AI Sitemap” albo custom PHP filter hooking w template_redirect + wp_query dla CPT posts/services/portfolio. Logika ta sama — render z WP_Query zamiast Astro collections.

Alternatywa dla Next.js: app/llms.txt/route.ts (App Router) z dynamic rendering, albo pages/llms.txt.ts (Pages Router) z getStaticProps. Next.js 14+ obsługuje plain text response przez new Response() identycznie jak Astro.

robots.txt dla AI crawlers

llms.txt to jedno. Pełny stack AEO wymaga też poprawnego robots.txt z explicit AI bot permissions:

User-agent: GPTBot
Allow: /
User-agent: OAI-SearchBot
Allow: /
User-agent: ChatGPT-User
Allow: /
User-agent: ClaudeBot
Allow: /
User-agent: anthropic-ai
Allow: /
User-agent: PerplexityBot
Allow: /
User-agent: Google-Extended
Allow: /
User-agent: CCBot
Allow: /
User-agent: *
Allow: /
Sitemap: https://yote.pl/sitemap-index.xml

Uwaga dla stron na Cloudflare: CF zones domyślnie mogą wstrzykiwać „Managed Content Signal” block, który disallowuje AI bots poprzez dyrektywę Disallow: / w podsekcji dla GPTBot/ClaudeBot/Meta/CCBot. Jest to feature opt-in („Instruct AI bot traffic with robots.txt”) włączany w Dashboard → Security Settings → Bot traffic.

Dla AEO wyłącz to. Ustawienie: Security Settings → Bot traffic → „Instruct AI bot traffic with robots.txt” = OFF. Dodatkowo: Overview → Control AI Crawlers → „Display Content Signals Policy” = uncheck (usuwa preamble „As a condition of accessing”).

Alternatywnie serwuj robots.txt dynamicznie z Worker (bypass injection layer), używając pliku src/pages/robots.txt.ts z prerender = false. Ten pattern wdrożony produkcyjnie na yote.pl — po wyłączeniu CF injection, AI bots dostają czysty Allow i zaczynają crawlować w ciągu 1-3 dni.

RSL 1.0 — Really Simple Licensing (opcjonalne)

Wrzesień 2025 proposal od rsl.dev. Header w llms.txt deklarujący licensing rights dla AI training:

# Inspirax
<!-- rsl:version=1.0 -->
<!-- rsl:ai-training=allow; credit=required -->
<!-- rsl:citation=preferred -->
> Agencja SEO i web development z Buska-Zdroju...

Komentarze HTML z prefiksem rsl: są ignorowane przez Markdown rendererów, ale AI crawlery implementujące RSL 1.0 parsują je jako directives. Kluczowe pola:

  • ai-training=allow|deny — czy content może być w training set
  • credit=required|optional — czy atrybucja jest wymagana przy cytowaniu
  • citation=preferred|required — priorytet linkowania źródła

Obecnie wsparcie: experimental. OpenAI deklaruje plany honorowania, Anthropic respektuje partially (w odpowiedziach Claude Search). Dla polskich stron: jeszcze niepowszechne, ale warto dodać jako future-proof signal — koszt zerowy, benefit potencjalnie duży kiedy spec zostanie zaadoptowany szerzej.

Alternatywa: .well-known/ai-policy (proponowana przez W3C w draft 2025) — separate file, bardziej formalny. W kwietniu 2026 nadal draft, nie produkcyjny.

Case study — llms.txt na yote.pl (Inspirax)

Inspirax wdrożył dynamic llms.txt w marcu 2026. Konkretne liczby:

  • ~40 URLi w sekcjach ## Usługi, ## Strony branżowe, ## Portfolio, ## Blog — wszystko auto-generated z content collections
  • ~1 800 znaków output (dobrze poniżej 10k limit — miejsce na wzrost do ~200 URLi zanim zajdzie potrzeba split na llms-full.txt)
  • Update co deploy — zero manual sync między content/ a /llms.txt
  • Efekt: yote.pl cytowany w Perplexity na query „agencja SEO Busko-Zdrój” (potwierdzone test, kwiecień 2026, pozycja 2/5 sources)

Dodatkowe sygnały pickup:

  • Cloudflare Analytics: ClaudeBot hits na /llms.txt 4-6x/tydzień (od marca)
  • GPTBot hits: 2-3x/tydzień (niższy bo OpenAI crawler jest mniej aktywny dla nowych stron)
  • Perplexity crawl-on-demand: triggered przy każdym query gdzie yote.pl matchuje entity

Kod źródłowy dostępny w repo Inspirax w pliku src/pages/llms.txt.ts (linkujemy do publicznego repo w przyszłej sesji).

Czego się nauczyliśmy:

  • ai_summary w frontmatter content to najlepszy fallback dla opisu w llms.txt (lepszy niż description, bo description jest SEO-optimized dla Google snippetu, a ai_summary jest AI-optimized dla cytowania)
  • Sortowanie wpływa na citation priority — dla blog nowsze posts na górze, dla usług po order field
  • Zawsze dołącz sekcję ## Dane firmy (NIP, REGON, adres) — AI entity resolution używa tego do disambiguation Twojej firmy od innych o podobnej nazwie

Podsumowanie — action items

TL;DR dla czytelnika, który ma 30 minut w weekend:

  1. Utworzyć public/llms.txt minimum zgodnie ze spec llmstxt.org (H1 + blockquote + sekcje H2 z linkami)
  2. Dodać explicit AI bots do robots.txt (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, OAI-SearchBot z Allow: /)
  3. Wyłączyć CF Content-Signal injection jeśli używasz Cloudflare (Security Settings → Bot traffic → OFF)
  4. Zmigrować na dynamic endpoint po przekroczeniu ~20 podstron (Astro/Next.js/WordPress — wszędzie ten sam pattern)
  5. Dodać llms-full.txt (rozszerzoną wersję) gdy core llms.txt przekroczy 10 000 znaków
  6. Monitor w Analytics — filtruj po User-Agent GPTBot/ClaudeBot/PerplexityBot, sprawdzaj hit rate na /llms.txt raz w miesiącu

Kiedy NIE robić llms.txt: jeśli masz stronę zablokowaną przed wszystkimi crawlerami intencjonalnie (admin panels, staging, privacy-first SaaS) — tam llms.txt byłby niespójny z polityką. W innych przypadkach: zrób, koszt minimalny, upside realny.

Co dalej? AEO to szerszy temat niż jeden plik. Następne kroki: schema.org markup (Organization, Service, FAQPage, HowTo), Person schema z knowsAbout, speakable sections, passage-level citability optimization. Każdy z tych elementów wzmacnia entity clarity i citation rate w AI Overviews.

Pełen pakiet AEO wdrażamy w ramach usługi AI Search (AEO) — schema markup, llms.txt, citability scoring i passage-level optimization. Jeśli chcesz pełny audyt AEO Twojej strony — oferujemy go jako osobną usługę (2 900 zł, report ~40 stron z priority action plan). Zawiera llms.txt generation, schema audit, robots.txt review, citability scoring dla top 10 stron. Alternatywnie — zacznij od bezpłatnego audytu online, który w 48h pokaże gdzie stoisz pod kątem AI search readiness.

Sources

Najczęstsze pytania

Czy llms.txt to oficjalny standard?

llms.txt jest proponowanym standardem społeczności (llmstxt.org, wrzesień 2024), NIE oficjalnym IETF RFC. Wsparcie deklarują: Anthropic (Claude), Perplexity (częściowo), OpenAI (docs reference). Google nie potwierdził oficjalnie, choć Gemini crawler respektuje strukturę podczas indeksacji.

Czy llms.txt zastępuje robots.txt?

Nie. robots.txt reguluje DOSTĘP crawlerów (allow/disallow), llms.txt dostarcza SEMANTYCZNĄ MAPĘ dla AI. Potrzebujesz obu plików. Dodatkowo sitemap.xml — tam trafia pełna lista URLs dla klasycznych wyszukiwarek.

Gdzie umieścić plik llms.txt?

Plik MUSI być dostępny pod /llms.txt w root domeny — np. https://yote.pl/llms.txt. Nie w podfolderze, nie w /docs/. Serwować z nagłówkiem Content-Type: text/plain; charset=utf-8.

Jaki jest limit wielkości llms.txt?

Spec rekomenduje do 10 000 znaków dla llms.txt (core). Jeśli potrzebujesz więcej (duża dokumentacja, rozbudowany katalog), utwórz dodatkowy llms-full.txt z pełnymi opisami — bez limitu.

Czy llms.txt wpływa na klasyczne SEO w Google?

Bezpośrednio — nie. Google Search nadal indeksuje HTML + sitemap.xml. Pośrednio — tak: Gemini i Google AI Overviews używają podobnych sygnałów entity recognition. Poprawna struktura llms.txt wzmacnia entity clarity, co koreluje z citation rate w AI Overviews.

Jak sprawdzić czy AI bots czytają mój llms.txt?

W Cloudflare Analytics filtruj po User-Agent: GPTBot, ClaudeBot, PerplexityBot, Google-Extended, OAI-SearchBot. Sprawdź logi server access dla ścieżki /llms.txt. Minimum 1-2 hits/tydzień dla średniej strony świadczy o crawl pickup.

Potrzebujesz pomocy z SEO?

Bezpłatny audyt Twojej strony — PDF z rekomendacjami w 48h.

Chcę bezpłatny audyt →
Zadzwoń Bezpłatny audyt SEO →