Przejdź do treści
barteq.eu

Post

Agenci AI czytają sieć i nikt im tego nie ułatwia

2 minuty czytania 464 słów

Agent AI wchodzi na twoją stronę tak samo jak przeglądarka: wysyła żądanie HTTP i dostaje odpowiedź. Różnica jest w tym, co z nią robi. Przeglądarka renderuje. Agent musi wywnioskować, gdzie w tym HTML-u jest treść.

I tu zaczyna się zabawa, bo większość stron odpowiada mu komunikatem „radź sobie”.

Problem w jednym zdaniu

Strona dla ludzi ma nawigację, stopkę, baner cookies, trzy skrypty analityczne i „polecane artykuły”. Strona dla agenta powinna mieć tekst. To nie znaczy, że trzeba budować dwa serwisy — wystarczy powiedzieć agentowi, że wariant istnieje.

Trzy nagłówki, które to załatwiają

Pierwszy: Vary: Accept. Mówi cache'om, że odpowiedź zależy od nagłówka Accept, więc nie wolno im podać wariantu HTML temu, kto prosił o markdown.

Drugi: Content-Type: text/markdown w wariancie tekstowym. Nie text/plain, nie application/octet-stream. Markdown ma własny typ.

Trzeci: Link: …; rel="alternate". To ten sam mechanizm, którego używa się do kanałów RSS — wskazówka „jest inna wersja tego zasobu i tu jest jej adres”.

Razem wygląda to tak:

GET /blog/agenci-ai-czytaja-siec/ HTTP/1.1
Accept: text/markdown
HTTP/1.1 200 OK
Content-Type: text/markdown; charset=utf-8
Vary: Accept
Link: </blog/agenci-ai-czytaja-siec.md>; rel="alternate"; type="text/markdown"
X-Robots-Tag: noindex

To ostatnie jest celowe. Wariant markdown ma być dostępny, ale nie ma po co konkurować z HTML-em w indeksie wyszukiwarki. Dla agenta to nie problem — agent nie czyta indeksu, tylko nagłówki.

Skąd agent ma wiedzieć, że to istnieje

Dobrą odpowiedzią jest plik, który opisuje blog maszynowo. Nazywa się llms.txt i jest w tym samym miejscu, w którym robots.txt był od zawsze: w katalogu głównym.

Rysunek ołówkiem: mały robot zaglądający przez bramę do ogrodu, obok tabliczka z adresem llms.txt
Mały robot czyta tabliczkę przy bramie — wariant dla maszyn jest zwykle obok tego dla ludzi.

W moim wydaniu ten plik zawiera:

  • jednozdaniowy opis bloga i informację, że autor pisze pod pseudonimem,
  • listę najnowszych postów z linkiem HTML i linkiem .md,
  • tabelę „jak pobrać treść”: HTML, .md, negocjacja przez Accept, pełny dump, sitemap,
  • sekcję z uwagami — na przykład to, że treść jest edukacyjna i nie jest zaproszeniem do testowania niczyich systemów.

Kluczowe: jeden plik mówi wszystko. Agent nie musi zgadywać konwencji ani próbować pięciu URL-i, żeby sprawdzić, który odpowie.

Sprawdź to w pięć sekund

# wariant dla ludzi
curl -sI https://barteq.eu/blog/agenci-ai-czytaja-siec/ | grep -i vary

# wariant dla agentów
curl -s -H 'Accept: text/markdown' \
  https://barteq.eu/blog/agenci-ai-czytaja-siec/ | head -5

# bezpośredni adres, bez negocjacji
curl -sI https://barteq.eu/blog/agenci-ai-czytaja-siec.md | grep -i content-type

# manifest
curl -s https://barteq.eu/llms.txt | head -20

Cztery komendy i wiesz, czy strona jest czytelna dla maszyny. Jeśli trzecia zwraca HTML, to znaczy, że ktoś uznał, że to niepotrzebne.

Jedno źródło, dwa opakowania

Łatwo tu o błąd: trzymać HTML w bazie i konwertować go do markdownu „w locie”. Wtedy masz dwa generatory i dwa różne teksty — ten sam problem, który mają wszystkie systemy tłumaczące treść tam i z powrotem.

Moje podejście jest odwrotne: markdown jest źródłem, HTML jest pochodną, renderowaną raz przy publikacji. Wariant .md to dokładnie ten sam tekst, który poszedł do HTML-a, zapisany bajt w bajt. Nie ma czego rozjeżdżać, bo nie ma drugiego generatora.

Po co to komu

Bo agent, który nie musi parsować HTML-a, robi trzy rzeczy lepiej:

  1. Cytuje dokładniej — nie gubi fragmentu, bo nawigacja wypadła w środku akapitu.
  2. Kosztuje mniej — mniej tokenów na to samo.
  3. Rzadziej się myli — mniej „nie wiem, który to był akapit”.

A dla autora jest jeszcze jedna korzyść: jak napiszesz wariant maszynowy raz, to przestajesz się zastanawiać, co zobaczy wyszukiwarka, a co robot. Oba widzą to samo, tylko w innym opakowaniu.