ANALIZA · NARZĘDZIA AGENTOWE 13 min czytania

Harness to nie model. Co naprawdę wybierasz, uruchamiając agentowe CLI

Instalując agentowe CLI, wybierasz dwie rzeczy naraz. Pierwsza to harness, czyli maszyneria wokół modelu. Druga to rodzina modeli. Sprawdziłem 1 września 2026, kto naprawdę skleja te dwie decyzje w jedną. Wyszło odwrotnie, niż mówi obiegowa wersja. Robią to Anthropic i Google. OpenAI, DeepSeek, Cline, Aider, OpenCode i Pi zostawiają wybór dostawcy otwarty.

Dwa układy obok siebie. Po lewej zszyty: blok harness i blok jednej rodziny modeli połączone spawem, podpis jedna decyzja. Po prawej rozdzielony: ten sam blok harness, pod nim jeden interfejs i trzy bloki dostawców, podpis dwie decyzje, druga odwracalna

Harness to obudowa modelu. Pętla agenta, zestaw narzędzi, kontekst, uprawnienia, sesje. To ona zamienia model odpowiadający na wiadomości w coś, co samo czyta repozytorium i odpala testy. Model to silnik w środku. Harness go wywołuje i nie jest z nim tożsamy.

Brzmi jak akademickie rozróżnienie i przestaje nim być w dniu, w którym chcesz zmienić model. Wtedy okazuje się, że decyzja zapadła miesiące wcześniej, przy wyborze narzędzia. Nikt jej wtedy nie zapisał. Wszystkie liczby i cytaty poniżej pochodzą ze źródeł, które da się otworzyć, i sprawdziłem je 1 września 2026. Gdzie czegoś nie potwierdziłem, piszę to wprost.

Cztery rzeczy, które nazywamy jednym słowem

Zacznijmy od pojęcia. „Harness” nie jest moim wymysłem. Anthropic używa tego słowa i sam je definiuje. W słowniku Claude Code stoi zdanie, które rozstrzyga całą dyskusję: „Claude Code is the harness; Claude is the model inside it”. Firmowy blog dorzuca definicję. Harness to „the software scaffolding around a model: the loop, tools, context management, and guardrails that turn raw intelligence into a working agent”.

Harness jest więc kategorią, a nie produktem. Produkty są cztery. Dokumentacja Anthropica zestawia je w jednej tabeli: „The Agent SDK, the CLI, the Client SDK, and Managed Agents each fit different needs”. Warto je rozdzielić. W rozmowach lecą jako jedno słowo.

Warstwa Co dostajesz Co piszesz sam
Client SDK Klienta API dla siedmiu języków. Wysyłasz żądanie, odbierasz odpowiedź. Całą pętlę narzędzi. Dokumentacja mówi wprost: „implementing the tool loop yourself”.
Agent SDK Gotowy harness jako biblioteka: „the same tools, agent loop, and context management that power Claude Code”. Plus hooki, podagentów, MCP, uprawnienia i sesje. Logikę swojej aplikacji. Pętla biegnie w Twoim procesie.
CLI Ten sam harness jako program w terminalu, do pracy interaktywnej. Nic. Z innego języka odpalasz go jako podproces z flagą -p.
Managed Agents „Pre-built, configurable agent harness that runs in managed infrastructure”. Orkiestracja zostaje po stronie Anthropica. Konfigurację. Sandbox postawisz u siebie, pętli nie.

Cztery pozycje, cztery odpowiedzi na jedno pytanie: ile maszynerii bierzesz gotowej. Żadna nie mówi nic o tym, jaki model siedzi na końcu. To osobna oś. Dopiero na niej robi się ciekawie.

Kto naprawdę skleja harness z dostawcą

Obiegowa teza brzmi tak: narzędzia od producentów modeli z natury trzymają się swoich modeli. Sprawdziłem ją w dokumentacji ośmiu narzędzi, a nie w opracowaniach o nich. W tej wersji się nie broni.

Narzędzie Licencja Dostawcy modeli według własnej dokumentacji
Claude Code Zamknięta. LICENSE.md: „© Anthropic PBC. All rights reserved.” Tylko Claude. Każde z sześciu wdrożeń serwuje tę samą rodzinę.
Gemini CLI Apache 2.0 Tylko Gemini. Trzy ścieżki logowania, wszystkie do Google.
Codex CLI Apache 2.0 Wbudowane identyfikatory openai, ollama i lmstudio, plus własny endpoint.
DeepSeek Harness MIT Warstwa modeli opisana jako „provider-neutral”. Anthropic i OpenAI dodajesz z konfiguracji.
Cline Apache 2.0 README: „Cline is not locked to a single AI provider”.
Aider Apache 2.0 „Aider can connect to most LLMs”. Ostatni commit z 22 maja 2026.
OpenCode MIT Dokumentacja: „75+ LLM providers”, plus modele lokalne.
Pi MIT README pakietu pi-ai: „Unified multi-provider LLM API (OpenAI, Anthropic, Google, etc.)”.

Odczyt z 1 września 2026. Wychodzi z tego coś innego, niż zapowiadała teza. Anthropic i Google są wyjątkami, a nie regułą. OpenAI zbudowało własne CLI i zostawiło w nim gotowe wpięcie na Ollamę i LM Studio. DeepSeek zbudował własny harness i opisał warstwę modeli jako neutralną wobec dostawcy. Sklejenie harnessa z rodziną modeli to decyzja dwóch konkretnych firm. Nie jest cechą narzędzi robionych przez producentów modeli.

Co dokładnie jest zamknięte po stronie Anthropica

Tu trzeba być precyzyjnym. Krąży wersja skrócona i nieprawdziwa: „Claude Agent SDK działa tylko z API Anthropica”. To nieprawda. Tabela na stronie wdrożeń zestawia sześć opcji. Claude for Teams i Enterprise, konsola Anthropica, Amazon Bedrock, Claude Platform on AWS, Google Cloud Agent Platform, Microsoft Foundry. Pod tabelą stoi siódma pozycja: własna brama, którą hostujesz przed pozostałymi trasami.

Masz więc pełną swobodę co do infrastruktury: wybierasz, kto Ci wystawia fakturę, w jakim regionie leci inferencja i jakim poświadczeniem się logujesz. Ta sama tabela nie ma jednak wiersza o modelu. Wszystkie sześć tras prowadzi do rodziny Claude. Aliasy opus i sonnet rozwijają się do builda Opusa i Sonneta u każdego dostawcy. Zamknięcie dotyczy rodziny modeli, nie endpointu i nie chmury. To jest cała różnica.

Jest jeszcze jedna furtka. Trzeba ją opisać uczciwie, bo pierwszy komentarz pod takim tekstem brzmi: „przecież puszczam Claude Code na GLM”. Rzeczywiście da się. Dokumentacja konfiguracji modeli mówi: „your provider or gateway defines the model names, so Claude Code passes any string through without checking it”. Anthropic sam podnosi ten przypadek na stronie o bramach. I odmawia mu wsparcia: „doesn't support routing Claude Code to non-Claude models through any gateway”. To granica wsparcia, a nie blokada techniczna, więc działa tak długo, jak każda inna niewspierana konfiguracja: do najbliższej zmiany po drugiej stronie.

Dochodzą jeszcze dwie rzeczy. Biblioteka istnieje w dwóch językach i dokumentacja stawia to jasno: „The SDK is available as a library for Python and TypeScript only”. Z innego języka odpalasz CLI jako podproces. Licencyjnie całość podlega warunkom komercyjnym Anthropica, nie licencji otwartej. Wdrażasz to w firmie? Przejrzyj przy okazji, co obejmuje aktywacja Claude Code w praktyce. Tam kończy się dokumentacja produktu, a zaczyna robota wdrożeniowa.

WSPÓŁPRACA

To robię na co dzień: doradzam przy strategii AI i buduję agentów, którzy przeżywają demo.

Pi rozkłada to na pakiety

Pi to otwarty toolkit agentowy na licencji MIT. Repozytorium earendil-works/pi powstało w sierpniu 2025. Miało 100 481 gwiazdek, gdy pytałem API GitHuba 1 września 2026. Plik LICENSE, jedyny w repozytorium, zaczyna się od „Copyright (c) 2025 Mario Zechner”.

Zamiast jednego zszytego produktu Pi daje pakiety. README wymienia pięć. pi-ai to zunifikowane API do wielu dostawców. pi-agent-core to rdzeń z pętlą i wywoływaniem narzędzi. pi-coding-agent to gotowe CLI. pi-tui obsługuje terminal, a pi-telemetry daje kontrakty telemetrii neutralne wobec dostawcy. To lista z README, a nie zawartość katalogu: w packages/ siedzi dziesięć katalogów. Trzy pominięte w README, pi-client, pi-protocol i pi-server, wyszły już na npm.

Napisał to Mario Zechner, ten sam, który zrobił libGDX. Dziś opisuje właścicielstwo inaczej, niż mówi skrót „Pi Maria Zechnera”. Pi należy do Earendil, spółki, którą Armin Ronacher, autor Flaska, założył razem z Colinem Daymondem Hanną. Zechner jest tam wspólnikiem i sam pisze, że o Pi decyduje razem z Arminem i Colinem. Przejście ogłoszono 8 kwietnia 2026, a stara ścieżka badlogic/pi-mono nadal przekierowuje na nowe repozytorium.

Dowód, że to działa, przyszedł od DeepSeeka

Najmocniejszy argument za rozdzielaniem tych warstw nie jest argumentem. Jest commitem w cudzym repozytorium.

DeepSeek otworzył własny harness 13 sierpnia 2026. Nazywa się DeepSeek Harness, ma licencję MIT i stoi na architekturze, w której wszystko jest wtyczką. W jego monorepo, w packages/llm/, obok adaptera do modeli DeepSeeka leży drugi pakiet: @deepseek-ai/dsh-llm-pi-ai. Jego README nazywa go adapterem wieloproviderowym. Każdą trasę obsługuje tam „@earendil-works/pi-ai”. Zaglądam do package.json i zależność stoi wprost, w wersji ^0.84.2.

Firma, która robi własne modele, zbudowała własny harness, a do warstwy wieloproviderowej wzięła cudzą bibliotekę zamiast pisać swoją. README tego pakietu wyjaśnia, po co. Trasę, której katalog pi-ai nie opisuje, deklarujesz ręcznie. Dzięki temu „an OpenAI-compatible gateway or self-hosted server is configuration, not a code change”. Dokładnie o tę korzyść chodzi w całym rozdzieleniu, opisaną słowami producenta modeli.

Zakres tej obserwacji podaję razem z nią. Pakiet ma wersję 0.1.2-alpha.4, a własny opis nazywa go bliźniakiem weryfikacyjnym adaptera DeepSeeka. To nie jest domyślna trasa produkcyjna. To dowód, że szew istnieje i że ktoś go użył. Sprawdziłem przy okazji krążące twierdzenie, że OpenClaw osadza sesję agenta przez createAgentSession() z pi-agent-core, i ono się nie potwierdza. OpenClaw ma własną funkcję o tej nazwie we własnym drzewie, a z paczek Earendil bierze tylko pi-tui. Powiązanie z Pi jest realne, ale innego rodzaju. Plik THIRD_PARTY_NOTICES mówi, że fragmenty OpenClawa zaadaptowano z Pi na licencji MIT.

Pięć warstw, które przepisujesz przy zmianie dostawcy

Tu kończy się teoria. Jeśli Twój harness jest zszyty z jednym dostawcą, przesiadka dotyka pięciu warstw. Poniżej konkrety z trzech natywnych API: Anthropica, OpenAI i Google.

Warstwa wywołania. Trzy API nie zgadzają się nawet co do tego, gdzie mieszka żądanie. Anthropic wysyła POST na stałe /v1/messages, OpenAI na /v1/chat/completions albo /v1/responses. Gemini wkłada nazwę modelu w ścieżkę URL i ma osobną metodę na strumień. Limit długości odpowiedzi też nazywa się inaczej u każdego: max_tokens, max_completion_tokens, max_output_tokens albo generationConfig.maxOutputTokens.

Format narzędzi. To samo narzędzie zapisujesz na cztery sposoby. Anthropic kładzie schemat JSON w input_schema, płasko obok nazwy. OpenAI w Chat Completions owija go w obiekt function z polem parameters. Własne Responses API OpenAI spłaszcza to z powrotem. Gemini zagnieżdża całość w tools[].functionDeclarations[].parameters i przyjmuje tam wybrany podzbiór OpenAPI, a nie pełny JSON Schema.

Gorsza jest droga powrotna, czyli oddanie modelowi wyniku narzędzia. Anthropic oczekuje bloku tool_result z tool_use_id wewnątrz wiadomości użytkownika. OpenAI w Chat Completions chce całej wiadomości z rolą tool i polem tool_call_id. Responses API chce elementu function_call_output z call_id. Gemini nie ma roli narzędzia i oczekuje części functionResponse z nazwą funkcji. Cztery różne operacje na to samo.

Kontekst. Sam prompt systemowy zapisujesz na co najmniej cztery sposoby. Anthropic ma parametr system. Chat Completions ma wiadomość system albo developer. Responses ma pole instructions. Google ma obiekt systemInstruction. Z rozumowaniem jest ostrzej. To, co wraca, jest nieprzezroczystą plombą wystawcy: signature u Anthropica, encrypted_content u OpenAI, thoughtSignature u Google. Odsyłasz to co do bajta temu, kto to wystawił. Nikt inny tego nie odczyta.

Uprawnienia. „Wymuś wywołanie narzędzia” to tool_choice: {"type": "any"} u Anthropica. U OpenAI to tool_choice: "required". U Google toolConfig.functionCallingConfig.mode: "ANY". Na brzegach mapowanie przestaje być jeden do jednego. Gemini ma tryb VALIDATED, którego nie ma nigdzie indziej. Ma też ustawienia bezpieczeństwa per żądanie, których Anthropic w ogóle nie wystawia. Sama polityka przenosi się bez zmian, czyli reguły mówiące, czego agent nie zrobi bez zgody człowieka. Jej zapis w wywołaniu API piszesz od nowa.

Telemetria. Zmiana nazwy prompt_tokens na input_tokens to łatwiejsza połowa. Trudniejsza jest ta, w której liczba zmienia znaczenie. Anthropic trzyma ruch z cache poza sumą wejścia. Każe dodawać input_tokens, cache_creation_input_tokens i cache_read_input_tokens. Google i OpenAI wliczają trafienie w cache do sumy promptu. Mapowanie po nazwach pól policzy więc inny wolumen i inny koszt dla identycznego żądania. Dashboard kosztów przeżyje przesiadkę tylko pozornie. Taki błąd wygląda dokładnie jak retry, który zwraca OK i chowa problem.

Czego wspólny interfejs nie wchłonie

Wspólna biblioteka, taka jak pi-ai czy LiteLLM, zdejmuje z Ciebie większość tej roboty. Dokumentacja LiteLLM obiecuje: „every response follows the OpenAI Chat Completions format, regardless of provider”. Zamiany w rodzaju input_schema na function.parameters naprawdę idą mechanicznie. Wchłanianie nie jest jednak całkowite, a szwy widać w zgłoszeniach do samej biblioteki. Schemat narzędzia z $ref albo anyOf trzeba przepisać, zanim Gemini go przyjmie. Spłaszczanie tury z rozumowaniem do kształtu OpenAI potrafiło zgubić bloki, których wymaga kolejne żądanie.

Zostaje też część, której żaden adapter nie przeniesie, bo format nie ma na nią miejsca. Specyfikacja opisuje kształt żądania i nic ponadto. Czy Twoje prompty nadal działają? Czy agent sięga po narzędzia wtedy, kiedy trzeba? Czy ewaluacja wychodzi tak samo? Schemat na to nie odpowiada. Dowiadujesz się, puszczając własny zestaw testów na nowym modelu. Pamiętaj o tym, kiedy szacujesz koszt przesiadki. Model językowy jest najtańszą pozycją w rachunku za agenta, a przepisanie integracji już nie.

Kiedy sklejenie jest dobrą decyzją

Rozdzielanie ma cenę. Trzeba ją powiedzieć głośno, bo inaczej cały ten tekst czyta się jak reklama Pi. Zespół, który nie zamierza zmieniać rodziny modeli, płaci złożonością i nie dostaje nic w zamian. Wspólny interfejs to kolejna zależność i kolejna warstwa do debugowania. To także miejsce, w którym nowa funkcja dostawcy pojawia się później niż w jego własnym SDK.

Gotowy harness od dostawcy daje więcej z pudełka. Hooki, podagenci, uprawnienia i sesje przeszły testy na jego własnym modelu, a nie na średniej ze wszystkich. Jeśli budujesz na jednej rodzinie i wiesz o tym, to jest właściwy wybór. Sam tak robię tam, gdzie ma to sens. Zbudowałem dashboard, który czyta artefakty po przebiegu multi-agentowym, wprost na jednym harnessie. Nie udaje, że jest przenośny.

Różnica leży w tym, czy tę decyzję ktoś podjął, czy tylko odziedziczył po narzędziu. Świadomy wybór jednej rodziny modeli to strategia. Ten sam stan bez decyzji to dług, o którym dowiesz się w najgorszym możliwym miesiącu.

Pytanie, które warto zadać raz w roku

Nie namawiam do przesiadki. Namawiam, żeby rozdzielić te dwie decyzje w głowie. Dopóki są sklejone, każda zmiana modelu wygląda na migrację i nikt jej nawet nie wycenia.

Sprawdź to na sobie jednym pytaniem. Ile roboty kosztowałoby jutro puszczenie tego samego zadania na innym modelu? Odpowiedź „trzeba by przepisać integrację” znaczy, że modelu nie wybrałeś. Wybrał go za Ciebie harness w dniu, w którym go instalowałeś.

Zrób z tego jedną stronę w dokumentacji projektu. Wypisz pięć warstw z tego tekstu i przy każdej zanotuj, ile dni pracy kosztowałaby zmiana. Wróć do tej kartki za rok. Jeśli liczby urosły, wiesz już, którą warstwę oddzielić jako pierwszą.

Najczęstsze pytania

Czym harness różni się od modelu?

Model odpowiada na wiadomości. Harness to maszyneria wokół niego: pętla agenta, narzędzia do czytania i zapisu plików, zarządzanie kontekstem, uprawnienia i sesje. Anthropic zapisuje ten podział w słowniku Claude Code jednym zdaniem: „Claude Code is the harness; Claude is the model inside it”. Harness to kategoria, a nie konkretny produkt. Ten sam harness może w zasadzie wołać różne modele, jeśli tak został zbudowany.

Czy Claude Agent SDK działa tylko z API Anthropica?

Nie. Tabela porównawcza na stronie wdrożeń Anthropica zestawia sześć opcji, w tym Amazon Bedrock, Claude Platform on AWS, Google Cloud Agent Platform i Microsoft Foundry. Masz więc wybór co do infrastruktury, regionu i rozliczenia. Wszystkie te trasy serwują jednak modele z rodziny Claude. Zamknięcie dotyczy rodziny modeli, a nie endpointu ani dostawcy chmury, i to jest różnica warta zapamiętania.

Da się uruchomić Claude Code na modelu spoza rodziny Claude?

Technicznie tak, przez własną bramę i zmienną bazowego adresu. Dokumentacja konfiguracji modeli mówi, że nazwy modeli definiuje Twój dostawca lub brama, a Claude Code przepuszcza dowolny łańcuch bez sprawdzania. Anthropic sam podnosi ten przypadek i odmawia mu wsparcia, pisząc, że nie wspiera kierowania Claude Code na modele spoza rodziny Claude przez żadną bramę. Traktuj to jako konfigurację niewspieraną, która działa do najbliższej zmiany po drugiej stronie.

Czym jest Pi i kto za nim stoi?

Pi to otwarty toolkit agentowy na licencji MIT, rozwijany jako monorepo w repozytorium earendil-works/pi. Zamiast jednego produktu daje pakiety: zunifikowane API do wielu dostawców, rdzeń agenta z pętlą i wywoływaniem narzędzi, bibliotekę interfejsu terminalowego, gotowe CLI do kodowania i kontrakty telemetrii. Napisał go Mario Zechner, twórca libGDX. Dziś Pi należy do spółki Earendil, założonej przez Armina Ronachera z Colinem Daymondem Hanną, a Zechner jest tam wspólnikiem i współdecyduje o kierunku projektu.

Czy w małym zespole warto rozdzielać harness od modelu?

Nie zawsze. Jeśli zespół nie zamierza zmieniać rodziny modeli, rozdzielenie kosztuje złożoność i nie daje nic w zamian. Gotowy harness od dostawcy jest przetestowany na jego własnym modelu i szybciej dostaje nowe funkcje. Ważne jest tylko to, żeby wybór jednej rodziny był decyzją, a nie skutkiem ubocznym instalacji narzędzia. Zapisz go i wróć do niego, kiedy zmieni się cennik albo pojawi się model wyraźnie lepszy w Twoim zadaniu.

SP

Szymon Paluch

ex-CTO · AI Strategy

Nie wiesz, ile kosztowałaby Cię zmiana modelu?

Przejdziemy przez Twój stack warstwa po warstwie i wyjdziesz z liczbą w dniach pracy, a nie z przeczuciem.

Umów rozmowę
Powiązane wpisy
Stack AI w GTM: pięć etapów do kupienia, cztery styki do ustalenia
Raport „Polaków portret własny”: dziewięć błędów, które widać w pliku
Ile kosztuje agent AI i co naprawdę decyduje o wycenie