Markdown for Agents w WordPress bez Cloudflare Pro — i pułapka która może zepsuć Twoją stronę

przez Łukasz | kwi 22, 2026

Artykuł 1 — czym jest agent-readiness i dlaczego większość stron WordPress startuje z 0/100

Artykuł 2rel="service-doc", strona /dla-agentow i pułapka LiteSpeed cache

Artykuł 3 — Markdown for Agents bez Cloudflare Pro i krytyczna pułapka z Vary: Accept

Artykuł 4 — Content Signals w robots.txt i dlaczego kolejność dyrektyw ma znaczenie

Artykuł 5 — JSON API z WordPress CPT i dwa domyślne błędy REST API

Artykuł 6 — diagnostyka przez curl, pełny raport w jednej chwili

Cloudflare oferuje funkcję „Markdown for Agents” — strona automatycznie serwuje Markdown zamiast HTML gdy agent o to prosi. Brzmi świetnie. Jest jeden problem: to funkcja płatna, dostępna od planu Pro.

Dobra wiadomość: mechanizm który za tym stoi jest otwarty i można go wdrożyć bezpośrednio w WordPress. Za darmo. Bez Cloudflare Pro.

Zła wiadomość: jeśli masz LiteSpeed Cache — jest jedna pułapka która może sprawić że Twoja strona zacznie serwować Markdown wszystkim użytkownikom. Łącznie z przeglądarkami.

Zacznijmy od początku.

Dlaczego agenci wolą Markdown

Agent AI przetwarza tekst w tokenach. Jeden token to mniej więcej trzy czwarte słowa — tyle mieści się w „jednostce przetwarzania” modelu językowego.

Typowa strona HTML zawiera mnóstwo rzeczy które dla agenta są bezużyteczne: tagi, atrybuty CSS, skrypty, nawigację, stopkę, widgety. Agent pobiera stronę — i 60-80% tego co pobiera to szum który musi odfiltrować zanim dotrze do treści.

Cloudflare zmierzył że serwowanie treści w czystym Markdown zamiast HTML redukuje zużycie tokenów nawet o 80%.

Dla agenta który przetwarza dziesiątki stron w jednym zadaniu — to różnica między szybką odpowiedzią a przekroczeniem limitu kontekstu.

Jak działa content negotiation

Rozwiązanie opiera się na mechanizmie który istnieje w HTTP od lat — content negotiation.

Gdy klient wysyła request do serwera, może zadeklarować w nagłówku Accept jakie formaty potrafi obsłużyć:

Accept: text/html
Accept: text/markdown
Accept: application/json

Serwer który obsługuje content negotiation — sprawdza ten nagłówek i serwuje odpowiedź w preferowanym formacie. Przeglądarka dostaje HTML. Agent który prosi o Markdown — dostaje Markdown.

To co robi Cloudflare Pro — przechwytuje requesty z Accept: text/markdown na poziomie edge i konwertuje HTML na Markdown przed odesłaniem odpowiedzi.

My zrobimy to samo, tylko bezpośrednio w WordPress.

Jak to działa w WordPress

Implementacja opiera się na hooku template_redirect który uruchamia się bardzo wcześnie w cyklu życia WordPress — zanim zostanie wygenerowany jakikolwiek HTML.

Logika jest prosta:

  1. Sprawdź nagłówek Accept w requeście
  2. Jeśli nie zawiera text/markdown — wyjdź, WordPress działa normalnie
  3. Jeśli zawiera — pobierz treść posta, przekonwertuj HTML na Markdown, wyślij odpowiednie nagłówki i zwróć Markdown

Konwersja musi obsłużyć: nagłówki H1-H6, pogrubienie i kursywę, linki, obrazy, listy, bloki kodu, cytaty, tabele, akapity. Na początku każdego dokumentu warto wygenerować YAML frontmatter z tytułem, URL i opisem — informacje które agent może użyć do kontekstualizacji treści bez czytania całości.

Do odpowiedzi dołączamy trzy nagłówki:

Content-Type: text/markdown; charset=utf-8
Vary: Accept
X-Markdown-Tokens: [szacunkowa liczba tokenów]

Vary: Accept informuje cache że odpowiedź zależy od nagłówka Accept — różni klienci powinni dostać różne wersje. X-Markdown-Tokens to szacunkowa liczba tokenów w dokumencie — agent może użyć tej wartości do zarządzania oknem kontekstu.

Brzmi prosto. I jest proste — do momentu gdy LiteSpeed wchodzi do gry.

Pułapka którą musisz znać

Wdrożyłem kod. Sprawdziłem przez curl:

bash
curl -sI https://webflux.pl/artykul/ -H "Accept: text/markdown" | grep content-type
# → content-type: text/markdown ✓

Działa. Sprawdziłem w Cloudflare checkerze — Content: 100/100.

Następnie sprawdziłem normalny request — bez nagłówka Accept: text/markdown:

bash
curl -sI https://webflux.pl/ | grep content-type
# → content-type: text/markdown

Zamiast HTML — Markdown. Dla wszystkich. Łącznie z przeglądarkami.

Co się stało: LiteSpeed Cache zacachował pierwszą odpowiedź — tę z Markdown — i zaczął serwować ją wszystkim użytkownikom niezależnie od nagłówka Accept.

Nagłówek Vary: Accept który dodałem powinien powiedzieć LiteSpeed żeby trzymał osobne wersje cache dla różnych wartości Accept. W teorii. W praktyce LiteSpeed zignorował to i serwował Markdown wszystkim.

Przez chwilę webflux.pl wyglądał tak dla każdego kto go odwiedził:

---
title: Agent Readiness
url: https://webflux.pl/...
source: webflux.pl
---

# Agent Readiness — jak przygotować stronę na erę AI
...

Niezbyt przyjazne dla czytelników. 😄

Rozwiązanie: jedna linia

php
header('X-LiteSpeed-Cache-Control: no-cache, no-store');

Ten nagłówek mówi LiteSpeed żeby nigdy nie cachował tej konkretnej odpowiedzi. Odpowiedzi Markdown są generowane dynamicznie przy każdym żądaniu agenta — co jest OK bo agenci to mały procent ruchu. Odpowiedzi HTML nadal trafiają do cache normalnie.

Dodaj tę linię do zestawu nagłówków — już jest w kodzie powyżej. Bez niej ryzykujesz że LiteSpeed „zaserwuje Markdown” wszystkim użytkownikom.

Weryfikacja że wszystko działa poprawnie

Dwa testy które musisz zrobić po wdrożeniu:

bash
# Test 1: agent dostaje Markdown
curl -sI https://twoja-strona.pl/artykul/ -H "Accept: text/markdown" | grep content-type
# Oczekiwany wynik: content-type: text/markdown; charset=utf-8

# Test 2: przeglądarka nadal dostaje HTML
curl -sI https://twoja-strona.pl/artykul/ | grep content-type
# Oczekiwany wynik: content-type: text/html; charset=UTF-8

Jeśli oba testy zwracają właściwe content-type — jesteś bezpieczny.

Możesz też sprawdzić jak wygląda wygenerowany Markdown:

bash
curl -s https://twoja-strona.pl/artykul/ -H "Accept: text/markdown" | head -30

Powinieneś zobaczyć YAML frontmatter i czysty tekst bez tagów HTML.

Dodatkowy nagłówek: X-Markdown-Tokens

Cloudflare w swojej implementacji dodaje nagłówek X-Markdown-Tokens z szacunkową liczbą tokenów w dokumencie. Agenci mogą używać tej wartości do zarządzania oknem kontekstu — decydować ile treści wczytać w jednym żądaniu.

Nasza implementacja też to obsługuje — szacunek oparty na długości tekstu, wystarczająco dokładny żeby agent wiedział z czym ma do czynienia.

Nie chcesz grzebać w kodzie?

Pełna implementacja Markdown for Agents — z obsługą LiteSpeed, Divi, Apache i Nginx, panelem ustawień i automatyczną diagnostyką — jest częścią pluginu Agent-Ready WP dostępnego wkrótce na iFox.pl.

Instalujesz, włączasz przełącznik, gotowe. Bez functions.php, bez ryzyka że coś się posypie po aktualizacji motywu.

Efekt końcowy

Po wdrożeniu Cloudflare checker powinien pokazać:

Content: 100/100

A Twoja strona zyskuje coś co Cloudflare oferuje w płatnym planie — serwowanie treści w formacie optymalnym dla agentów, bez przepłacania za infrastrukturę.

Co dalej

Mamy już sygnał dla agentów i efektywne serwowanie treści. Zostało nam powiedzieć agentom co mogą z tą treścią zrobić.

W następnym artykule dodajemy Content Signals do robots.txt — trzy dyrektywy które deklarują Twoje preferencje wobec AI. I wyjaśniam dlaczego kolejność tych dyrektyw w pliku ma znaczenie którego nikt nie dokumentuje.


Ten artykuł jest częścią serii „WordPress Agent-Readiness”. Wszystkie wdrożenia zostały przetestowane na webflux.pl — włącznie z błędami i ich naprawą.

Agent kończy, ale zadania nie wykonał

Agent kończy, ale zadania nie wykonał

Objawy Agent odpowiada: „Przygotowałem i wysłałem potwierdzenie do klienta." Potwierdzenie nie zostało wysłane. Albo: „Zaktualizowałem wszystkie rekordy" — zaktualizował trzy z dwunastu. Albo: „Nie znalazłem żadnych zamówień" — bo narzędzie zwróciło błąd, którego nikt...

Agent zrobił coś, o co nikt nie prosił

Agent zrobił coś, o co nikt nie prosił

Objawy Operacja, której nikt nie zlecił. Dane wysłane pod adres, którego nie ma w żadnej konfiguracji. Rekord zmieniony poza zakresem zadania. Odpowiedź, z której wynika, że agent dostał instrukcje od kogoś innego niż ty. Cecha wspólna: technicznie wszystko zadziałało...

Agent zrobił to samo dwa razy

Agent zrobił to samo dwa razy

Objawy Ten syndrom różni się od pozostałych jedną rzeczą: objaw widzi klient, nie ty. Trzy identyczne wiadomości w skrzynce. Dwa zamówienia zamiast jednego. Podwójne obciążenie. Duplikaty rekordów, które ktoś zauważa tydzień później. W twoim dzienniku wszystko wygląda...

Agent gubi wątek w długim zadaniu

Agent gubi wątek w długim zadaniu

Objawy Pierwsze kroki idą wzorowo. Po kilkunastu agent zaczyna się rozjeżdżać. Przestaje przestrzegać reguły z promptu systemowego, której trzymał się na początku. Zmienia format odpowiedzi w połowie zadania. Wraca do czegoś, co już ustalił, i ustala to inaczej....

Agent podaje dane, których nie ma

Agent podaje dane, których nie ma

Objawy Numer zamówienia w idealnym formacie, którego nie ma w bazie. Kwota, której w dokumencie nie ma. Nazwa pola API, które nigdy nie istniało. Cytat z regulaminu, brzmiący dokładnie jak reszta regulaminu i w nim nieobecny. Cecha wspólna wszystkich tych przypadków:...

Działał wczoraj, dziś nie działa

Działał wczoraj, dziś nie działa

Objawy Nic się nie wywala. Nie ma wyjątków, nie ma timeoutów, dziennik wygląda tak samo jak zawsze. Po prostu odpowiedzi są gorsze. Postacie, w jakich to się objawia: Jakość. Agent zaczyna pomijać kroki, które wcześniej wykonywał, albo odpowiada ogólniej. Format....

Agent wybiera złe narzędzie

Agent wybiera złe narzędzie

Objawy Agent odpowiada nie na to pytanie. Pobiera listę zamówień, gdy pytano o jedno konkretne. Odpowiada z pamięci, choć miał sprawdzić w bazie. Albo sięga po właściwe narzędzie i wpisuje w argumenty coś, czego nie da się użyć. Sygnał, który odróżnia ten syndrom od...

Agent kręci się w kółko

Agent kręci się w kółko

Objawy Agent wykonuje kolejne obroty pętli, nie zbliżając się do zakończenia zadania. W dzienniku widać jedną z trzech postaci. Powtórzenie. To samo narzędzie, te same argumenty, raz za razem — czasem dziesiątki razy pod rząd. Oscylacja. Agent wywołuje na przemian dwa...