Dlaczego agenci kodujący ciągle reinwentują przeglądarkę
Dlaczego długotrwałe agenty do programowania dążą do narzędzi w kształcie przeglądarek: skrypty pomocnicze, pliki cookie jako pamięć, kompaktowe wyświetlanie stron, alternatywy HTTP oraz uprzedzenia w danych treningowych.
Przeglądarka, o której nikt nie prosił
Agenty kodujące wykazują powtarzalny wzorzec zachowań. Dzięki darmowemu dostępowi do sieci, możliwości pisania i wykonywania kodu oraz pracy trwającej wystarczająco długo, mają tendencję do tworzenia czegoś, co przypomina przeglądarkę. Motywacją nie jest chęć posiadania przeglądarki – agenci dążą do taniego, wielokrotnie używalnego narzędzia, które potrafi otworzyć adres URL, kliknąć, wypełnić formularze, czekać na dane i je pobrać, przechowywać pliki cookie i sesje oraz zrobić zrzut ekranu po niepowodzeniu. Patrząc na to w ten sposób, jest to zwykła praca inżynierska, jaką wykonałby zwykły programista.
Chromium jako produkt nie jest celem końcowym – agenci dążą do funkcji, jaką pełni przeglądarka: przekształcania protokołów i konwencji sieciowych w konkretne operacje.
Produkt kontra abstrakcja
Przeglądarka w rozumieniu Chrome lub Firefox to duża aplikacja: karty, pasek adresu, silnik renderowania, model procesów. Nic z tego nie jest tym, czego potrzebuje agent. On potrzebuje podstawowej funkcji przekształcania sposobu działania sieci w operacje, które można wykonać.
Ludzie korzystają z tej interfejsu, nie zauważając tego. Strona logowania oczywiście prosi o dane logowania, przycisk oczywiście można nacisnąć, więc naciskasz go, czekasz na następną stronę i kontynuujesz. Agent nie może polegać na tym nieujawnionym porozumieniu, więc musi przekształcić tę samą pracę w wyraźne operacje. Jeśli poprosisz agenta programistycznego o pracę na dowolnych stronach internetowych, dajesz mu problem, którego naturalna abstrakcja jest już znana, więc będzie dążył do tego rozwiązania.
Współczesna sieć internetowa również nie została stworzona tak, aby mogła być używana jako uporządkowana API. Zazwyczaj mamy do czynienia z dokumentem HTML otoczonym kodem JavaScript, a także sesjami logowania, plikami cookie, przekierowaniami, renderowaniem po stronie klienta, nieskończonym przewijaniem, oknami powiadomień, przesyłaniem plików oraz żądaniami asynchronicznymi. Zwykłe żądanie HTTP GET to dopiero początek – rzeczywiste zadania w takim środowisku wymagają ostatecznie realizacji takich operacji.
open(url)
click(selector)
fill(selector, text)
wait_for(selector)
extract(selector)
go_back()
screenshot()
To nie jest przeglądarka graficzna, ale bez wątpienia stanowi interfejs wielozadaniowy do sieci.
Dlaczego długie zadania wymagają narzędzi pomocniczych
Krótkie zadania można wykonać ad hoc. Jednorazowe wyszukiwanie można przeprowadzić metodą prób i błędów bez żadnej infrastruktury, ponieważ nie będzie się powtarzać i zakończy się w ciągu kilku sekund.
"Find the current exchange rate."
"Look up this company's homepage."
"Find the opening hours of this restaurant."
Praca trwająca długi czas jest inna. Wyobraź sobie agenta, który co kilka godzin monitoruje setki stron, wielokrotnie uruchamia skomplikowany proces pracy, pobiera treść stron pozostając zalogowanym, gromadzi dane przez kilka dni lub sprawdza stan usługi, aż coś się zmieni. Jeśli model musi obsłużyć każdy kliknięcie i każdą inspekcję, koszty gwałtownie rosną. Prosty sposób działania wygląda tak:
- Otwórz przeglądarkę, która służy do pobierania strony.
- Przeglądaj stronę, używając zrenderowanego DOM jako źródła informacji.
- Znajdź pole wyszukiwania, wpisz zapytanie, kliknij „Wyszukaj” i czekaj.
- Wydobyj dane.
- Przemyśl je.
- Powtórz.
Zdolny agent reaguje w sposób podobny do ludzkiego programisty, tworząc ponownie używalny pomocnik. Następny proces wygląda wtedy tak:
- Uruchom skrypt.
- Sprawdź, czy wynik nadal jest prawidłowy.
- Wzywaj model ponownie tylko wtedy, gdy tego nie robi, na przykład gdy selektor zwraca puste wyniki, zmienia się struktura strony lub wydobyte dane już nie odpowiadają temu, czego oczekuje zadanie.
To duża zmiana architektoniczna. Model przestaje wykonywać wszystkie operacje. Staje się elementem, który decyduje, jaka procedura powinna zostać uruchomiona, podczas gdy zwykłe oprogramowanie używa wybranego narzędzia i zbiera dane. Innymi słowy, agent kompiluje swoje doświadczenia w skrypt.
Eksploracja w przeglądarce, odtwarzanie w kodzie
Przeglądarka to doskonałe miejsce do eksploracji. Agent może badać różne opcje, nawigować, obserwować wyniki i ustalić, jaka sekwencja działań pozwoli osiągnąć cel. Ponowne rozważanie każdej z tych działań jest marnotrawstwem zasobów.
Załóżmy, że agent dowiaduje się, iż znalezienie produktu na stronie zakupowej zawsze oznacza przejście na stronę główną, wyszukiwanie frazy „kable USB-C”, zastosowanie filtrów dotyczących ocen co najmniej czterech gwiazdek, szybkiej dostawy oraz określonego limitu ceny, przeglądanie wyników oraz wyodrębnianie tytułów, cen i identyfikatorów produktów. Nie ma powodu, aby model językowy za każdym razem na nowo wykonywał te pięć operacji. Może je przekształcić w procedurę i wykorzystywać ją do podobnych problemów. Wymaga to jednak żywej sesji z plikami cookie, dlatego agent wybiera Puppeteer, Playwright lub coś podobnego jako narzędzie do pobierania stron.
async function getNewProducts(query) {
const browser = await playwright.chromium.connectOverCDP(
`wss://${AUTH}@brd.superproxy.io:9222`,
);
const page = await browser.newPage();
await page.goto("https://example.com/products");
await page.fill("input[name=q]", query);
await page.click("button[type=submit]");
await page.waitForSelector(".results");
return extractResults(page);
}
Fragment ten łączy Playwright z przeglądarką hostowaną zdalnie za pośrednictwem protokołu Chrome DevTools. Przeglądarka hostowana jest przydatna, gdy agent działający przez długi czas musi utrzymywać swoją sesję aktywną co kilka godzin, bez udziału modelu. Wymaga ona danych logowania sformatowanych jako ciąg połączeniowy, który reprezentuje zmienna ${AUTH}.
Strukturalne wydobywanie danych w sposób powtarzalny na stronie bez gotowego skrapera nie wymaga nawet lokalnego pliku Playwright. Ten sam proces może zostać przekształcony w narzędzie do skrapowania hostowane online: opisuje się potrzebne dane prostym językiem, otrzymuje się generowany kolektor i uruchamia się go bez użycia modelu w pętli kliknięć. Jego funkcje interakcji i parsowania to takie same operacje jak otwarcie, kliknięcie, wypełnienie, oczekiwanie, wydobywanie danych i robienie zrzutu ekranu, tylko w wersji hostowanej.
Taki skrypt zawodzi, gdy zmieniają się selektory CSS, zmuszając agenta do ponownego badania sytuacji i napisania nowego skryptu. Jeśli ta procedura znajduje się w narzędziu hostowanym, sztuczna inteligencja może ją naprawić bez konieczności ponownego pisania selektorów przez kogokolwiek.
Ludzcy programiści zachowują się w ten sam sposób. Pierwsza wizyta na stronie internetowej uczy, jak ona funkcjonuje, a potem nikt nie zastanawia się nad każdym kliknięciem. Gdy strona się zmienia, trzeba ją ponownie poznać, chociaż wiedzę tę przechowujemy nieświadomie. Sztuczna inteligencja ma znacznie droższe „pamięć”. Jeśli musi za każdym razem odbudowywać procedurę na podstawie kontekstu, płaci za to samo odkrywanie wielokrotnie. Dlatego zapisuje nauczony proces w skrypcie i go uruchamia, dopóki strona przestaje odpowiadać wymaganiom.
Cookies jako pamięć poza modelem
Żaden model językowy nie może przechowywać długotrwałej sesji internetowej w swoim kontekście, przynajmniej obecnie. Zapisywanie pliku .py nadal wywołuje model, podczas gdy przechowywanie plików cookie tego nie robi. W miarę trwania sesji przeglądarka sama gromadzi pamięć, więc znajduje się już poza zasobami przechowawczymi agenta. Składa się ona z trzech istotnych części:
- Pudełko z plikami cookie, w tym HttpOnly cookies oraz te ustawiane przez JavaScript po zalogowaniu lub sprawdzeniu bota. Często model w ogóle nie może ich odczytać, mimo to przeglądarka je przechowuje i dołącza do następnej żądania.
- Przechowywanie pochodzenia, czyli
localStorage,sessionStoragei IndexedDB, które zawierają niemal wyłącznie wartości napisane przez stronę. - Historia sesji, stos przeglądania wstecz i do przodu, który umożliwia działanie funkcji
back()lubtabs.goBack().
Część stanów istnieje poza sklepem z przeglądarkami, takich jak sesja po stronie serwera lub adres URL, który nie istnieje, dopóki nie zostanie uruchomiony JavaScript. Agent nie musi tego sam czytać – wystarczy mu sterować warstwą przeglądarki, która już zawiera tę sesję.
Ryzyka bezpieczeństwa związane z przekazywaniem przeglądarki
Gdy agent może czytać dowolną stronę i dowolne pliki cookie oraz sterować aktywną sesją, iniekcja poleceń przestaje być kwestią lepszych poleceń i staje się zagrożeniem architektonicznym. Każdy system obsługujący aktywną przeglądarkę musi się z tym zmierzyć, ale agenci kodujący są w gorszej sytuacji, ponieważ zazwyczaj mogą pisać i uruchamiać wszystko, na co natrafią. Ograniczaj to, co agent może robić bez nadzoru osoby, zaczynając od środowiska sandbox.
Dobrym wzorem jest lista kontrolna Anthropic dotycząca używania komputera: należy używać dedykowanej maszyny wirtualnej lub kontenera, unikać logowania chyba że zadanie tego wymaga, utrzymywać listy dopuszczalnych domen oraz wymagać zatwierdzenia przez człowieka wszystkiego, co dotyczy pieniędzy lub zgody.
Dlaczego surowy HTML to kiepski wprowadzany tekst
Surowe strony są okropnym źródłem danych dla modeli językowych, ponieważ zawierają mnóstwo niepotrzebnego „hałasu”. To, czego potrzebuje agent, może być ukryte w tysiącach tokenów związanych z formatowaniem, stylizacją i mechanizmami aplikacji. Dlatego dobry narzędzie przeglądarki zwraca mniejszą liczbę możliwych działań i obserwacji zamiast pełnego HTML.
Rysunek przedstawia Model Obiektów Dokumentu strony HTML – drzewo, które musi zostać skrócone w celu uzyskania zwięzłego widoku lub drzewa dostępności. Przydatne narzędzie może przekształcić je w coś znacznie mniejszego. Zamiast całego dokumentu może dostarczyć modelowi krótki zarys, jak ten.
Title: Search results
Links:
[1] Home
[2] Next page
Forms:
search: input[name=q]
Buttons:
submit: button[type=submit]
Main content:
...
Albo może ujawnić drzewo dostępności.
- navigation
- link "Home"
- link "Search"
- main
- heading "Results"
- list
- listitem "Item 1"
- listitem "Item 2"
Ta forma jest znacznie bliższa temu, co może wykorzystać model rozumowania. Warstwa o kształcie przeglądarki więc robi więcej niż tylko umożliwia interakcję: sprowadza środowisko do zwięzłego zestawu działań i obserwacji. Agent widzi jedynie te elementy sieci istotne dla swojego zadania, a nie mechanizmy odpowiadające za renderowanie stron. Kontekst jest zachowywany, wnioskowanie staje się tańsze, a błędy często, choć nie zawsze, zmniejszają się.
Istnieje jednak zastrzeżenie: pełny zrzut stanu dostępności z każdym odniesieniem może okazać się większy od widocznego tekstu. Kompresja ma sens tylko wtedy, gdy warstwa otaczająca faktycznie zwraca krótki, łatwy do obsługi wykaz elementów sterujących. Długość tego wykazu zależy od modelu. Mały model nie może korzystać z surowego DOM, natomiast silny model może to robić, ale nadal musi płacić za tokeny. Żaden z nich nie potrzebuje pełnego HTML.
Gdy zwykły HTTP wystarcza
Gdy agent nauczy się, jak działa strona, najtańsza i najbardziej niezawodna implementacja może wcale nie wymagać automatyzacji przeglądarki. Czasami okazuje się, że przeglądarka robi w tle coś dość prostego. Przycisk „Następna strona” może ostatecznie wykonywać właśnie to.
GET /api/products?page=2
Gdy tak się dzieje, renderowanie strony jest bezcelowe, a agent może bezpośrednio wywołać endpoint. Rezultatem jest drabina opcji.
human interface
↓
browser automation
↓
discovered workflow
↓
direct HTTP/API calls ← only if the site still allows it
Jego wartość polegała na pokazaniu, jak zachowuje się aplikacja. Gdy to zostanie zrozumiane, agent może usunąć dodatkowe warstwy i czasami przejść na zwykły HTTP. Agent, który nigdy nie korzysta z stron obciążonych JavaScriptem, może całkowicie pominąć automatyzację przeglądarki i polegać wyłącznie na HTTP, najlepiej z usługą rozwiązywania problemów z blokadami w gotowości na wypadek odrzuconych żądań. Niezależnie od wybranej drogi, autonomiczne agenty potrzebują planu awaryjnego, ponieważ na otwartej sieci prawie na pewno występują bariery Cloudflare lub kontrole anty-botów. Bez taniego mechanizmu ponawiania prób model błądzi, zużywa tokeny i zwiększa rachunek.
Istnieją dwie komplikacje.
Po pierwsze, wiele stron nie da się sprowadzić do formatu HTTP. Większość z nich nie pozwala na ich inżynierię wsteczną: ograniczają ruch pochodzący z innych narzędzi niż przeglądarki, zmieniają selektory, identyfikują klientów oraz dodają kontrole anty-botów lub CAPTCHY. W takich przypadkach należy zachować pełne podejście oparte na przeglądarce, zarówno lokalnie, jak i w chmurze.
Po drugie, rozwiązanie awaryjne nie zawsze się opłaca. Udokumentowana, publiczna API w formacie JSON ma określoną strukturę, jest ograniczona i łatwa do logowania. Inna sprawa to wewnętrzny punkt końcowy bez dokumentacji, który agent odkrył samodzielnie: faktycznie łatwiej go wywołać, ale trudniej jest go sprawdzić niż skryptu klikającego widoczną przycisk, przy czym logi są skromniejsze. Odpowiedź 200 wypełniona błahostkami łatwo umknąć uwadze, podczas gdy zepsuta strona rzuca się w oczy.
Ostatecznie agent nie jest lojalny wobec przeglądarek. Chce mieć najtańszy interfejs z otoczeniem, który nadal funkcjonuje:
- Jeśli tym interfejsem jest punkt końcowy w formacie JSON i strona go obsługuje, użyj JSON.
- Jeśli potrzebna jest eksploatacja JavaScripta oraz stan sesji, użyj prawdziwej przeglądarki za pośrednictwem Puppeteer lub Playwright, albo przeglądarki hostowanej.
- Jeśli potrzebny jest tylko pobraany plik HTML, użyj protokołu HTTP, z proxyem lub narzędziem do usuwania blokad, jeśli żądanie GET jest zablokowane.
Agenty internetowe o długim czasie działania zazwyczaj wykorzystują kilka z tych metod jednocześnie. Kluczową umiejętnością jest umiejętność przechodzenia w górę i w dół hierarchii w zależności od sytuacji.
Czy dane treningowe to wyjaśniają?
Odpowiedź jest mieszana. Dane treningowe mogą tłumaczyć, dlaczego model wybiera Playwright lub Puppeteer, ale nie mogą wyjaśnić konieczności stworzenia narzędzi przypominających przeglądarkę od samego początku.
Badanie przeprowadzone w 2026 roku przez Oxford i Microsoft pod nazwą BiasBusters sprawdzało bliskiego krewnego tego pytania, a mianowicie to, czy ekspozycja podczas szkolenia wpływa na wybór narzędzia przez model. Zespół kontynuował szkolenie małego modelu na korpusie bogatym w metadane dotyczące jednej konkretnej usługi pogodowej API, jednej z kilku oferujących tę samą usługę.
- Wcześniej model prawie nigdy nie wybierał tej API – zaledwie 0,6% czasu, co odpowiadało mniej więcej prawdopodobieństwu wynikającemu wyłącznie z przypadku.
- Po szkoleniu na zniekształconym korpusie była ona wybierana w około 12% przypadków, czyli dwadzieścia razy częściej.
Krótko mówiąc, samo narażenie na dane podczas treningu, niezależnie od zadania, w sposób mierzalny wpływa na to, który narzędzie lub produkt preferuje model. Chodzi tu jednak o wybór narzędzia. Abstrakcja (otwórz, kliknij, wypełnij, poczekaj, wydobyj w formie kształtu – bez względu na to, która biblioteka to umożliwia) jest określana przez środowisko. Model, który nigdy nie widział Playwright, nadal potrzebuje czegoś do otwierania stron, czekania na zawartość i raportowania wyników, ponieważ strony interaktywne tego wymagają.
Działają tu dwie odrębne rzeczy:
- Abstrakcja operacji
open,click,fill,waitiextractjest narzucana przez środowisko. Strony interaktywne zawierają elementy nawigacyjne, kontrolery czasowe, elementy sterujące oraz wygenerowany wynik, niezależnie od tego, czy Playwright występuje w wagach modelu. - Narzędzie Playwright w porównaniu z lokalnie opracowanym klientem pochodzi z tego, co model widział, jak pokazało BiasBusters w przypadku wymiennych interfejsów API.
Dane treningowe obejmują ten drugi przypadek, ale pomijają pierwszy. Nie potrafi wyjaśnić, dlaczego problem ciągle skupia się na abstrakcjach przypominających przeglądarki. Podstawowym powodem jest to, że sieć internetowa jest już zorganizowana w taki sposób.
Adaptery o najlepszych rezultatach
Agenty takie jak Claude Code tak naprawdę nie tworzą przeglądarek. Tworzą adaptery pomiędzy systemem rozumowania a środowiskiem, które przypadkowo ma kształt przeglądarki.
Biologia ewolucyjna ma pojęcie zwane karcynizacją: dziwną tendencję niepowiązanych ze sobą skorupiaków do stopniowego przybierania kształtu przypominającego kraba z upływem czasu.
Te gatunki nie doszły do wniosku, że bycie krabem to mądry pomysł. Ich otoczenie po prostu wciąż nagradzało mniej więcej tę samą odpowiedź na mniej więcej te same problemy. Agenci kodujący mogą podążać podobną ścieżką. Zauważają, że obecne podejście jest powolne, więc piszą skrypt, dodają próby ponownych działań w przypadku niepowodzenia, wprowadzają utrzymywanie sesji po zalogowaniu oraz ekstrakcję DOM lub informacji o dostępności, gdy strony stają się zbyt duże, by można je było zrozumieć.
The task requires the web.
↓
The web exposes a browser-shaped interface.
↓
The agent needs a way to operate that interface.
↓
Repeated operations make ad-hoc reasoning expensive.
↓
The agent writes reusable tools.
↓
Those tools accumulate state, retries, and abstractions.
↓
The tools start looking like a browser.
↓
Known workflows get compiled into deterministic code.
↓
The page changes so the agent re-explores.
↓
If an API exists, use it to get the data.
If not, and the site allows it, fall back to regular HTTP.
If not, stay on the browser.
Przy wystarczającej liczbie rund wynik przypomina doskonale mały przeglądarkę. To lepszy model mentalny dla agentów autonomicznych niż wyobrażanie sobie cyfrowych istot o dziwnym zainteresowaniu przeglądarkami. Zachowują się jak dobrzy inżynierowie – badają złożone środowisko, identyfikują rzeczywisty interfejs, jaki oferuje, oraz tworzą abstrakcje wokół tego, co jest powtarzalne, zależne od stanu i wymagające dużych nakładów. Internet posiada już stary i niezwykle skuteczny narzędzie abstrakcji do tego celu, a nazywa się ono przeglądarką.