Przejście do treści

Agenci AI i ich tożsamość — dlaczego persona jest ważniejsza od promptu i ile kosztuje w tokenach

Nadanie agentowi wyraźnej tożsamości — zakresu, narzędzi, stylu, definicji ukończenia — to najtańszy sposób na poprawę jakości i najdroższa pozycja na rachunku za tokeny, jeśli zrobi się to bez zrozumienia mechaniki. Oto inżynieria i matematyka.

Paweł Rudnicki
11 min
  • AI Agents
  • Claude API
  • Prompt Caching
  • Tokens
  • LLM

Wstęp

W 2026 roku "napisz dobry prompt" przestało być architekturą. Zespoły, z którymi pracuję, nie budują już jednego wielkiego promptu obsługującego wszystko. Budują agentów: wyspecjalizowane jednostki z własnym zakresem odpowiedzialności, własnym zestawem narzędzi i własną tożsamością.

Brzmi jak kosmetyka? Nie jest. Tożsamość agenta to jednocześnie najtańszy sposób na poprawę jakości odpowiedzi i najdroższa pozycja na rachunku za tokeny — jeśli zbudujesz ją bez zrozumienia tego, co dzieje się przy każdym pojedynczym zapytaniu.

Ten artykuł dotyczy trzech rzeczy: z czego naprawdę składa się tożsamość agenta, dlaczego zmienia zachowanie modelu i jak dokładnie przekłada się na tokeny oraz pieniądze.

Czym jest "tożsamość" agenta

Tożsamość to nie imię i miłe przywitanie. W praktyce to pięć warstw, a każda z nich jest nośna:

WarstwaNa jakie pytanie odpowiadaGdzie żyje
Rola i zakresDo czego ten agent służy — i do czego wprost NIE służy?System prompt
Granica narzędziJakie akcje może w ogóle wykonać?Definicje narzędzi
Styl i formatJak raportuje? Proza, JSON, diff?System prompt + structured outputs
Definicja ukończeniaKiedy zadanie jest skończone?System prompt
PamięćCo wie z poprzednich sesji?Narzędzie memory / zewnętrzny store

Najciekawsze jest to, że te warstwy nie są dokumentacją dla ludzi. Są przestrzenią poszukiwań, w której operuje model. Wąska, jawna tożsamość eliminuje całe klasy błędnych decyzji, zanim model je podejmie.

using Anthropic;
using Anthropic.Models.Messages;

// Tożsamość to stabilny artefakt — traktuj ją jak kod, nie jak literał
// stringa rozsiany po codebase. Wersjonuj, przeglądaj w review, testuj.
const string ReleaseAuditorIdentity = """
    Jesteś audytorem release'ów aplikacji mobilnej w .NET MAUI.

    ZAKRES: przeglądasz diff release candidate i raportujesz ryzyko.
    Nie piszesz funkcjonalności, nie refaktoryzujesz, nie dotykasz
    konfiguracji CI.

    METODA: dla każdego zmienionego pliku klasyfikuj ryzyko jako
    niskie / średnie / wysokie i uzasadnij je konkretnym scenariuszem
    awarii, nie ogólną obawą.

    OUTPUT: tabela znalezisk posortowana po istotności, następnie jedna
    rekomendacja go / no-go. Bez wstępu, bez streszczania własnych kroków.

    DONE: każdy zmieniony plik z diffa pojawia się w tabeli dokładnie raz.
    """;

AnthropicClient client = new();

var response = await client.Messages.Create(new MessageCreateParams
{
    Model = "claude-opus-5",
    MaxTokens = 16000,
    Thinking = new ThinkingConfigAdaptive(),
    OutputConfig = new OutputConfig { Effort = Effort.High },
    System = new List<TextBlockParam>
    {
        new() { Text = ReleaseAuditorIdentity },
    },
    Messages = [new() { Role = Role.User, Content = releaseDiff }],
});

Dlaczego tożsamość jest ważniejsza od sformułowania promptu

Zawęża przestrzeń decyzji

Agent bez zadeklarowanego zakresu traktuje każde zapytanie jako zaproszenie do bycia ogólnie pomocnym. Dokładnie tak powstaje code reviewer, który zaczyna refaktoryzować, albo ekstraktor danych, który dokłada uprzejme komentarze, wokół których potem trzeba parsować. "ZAKRES / poza zakresem" robi więcej roboty niż trzy akapity grzecznych instrukcji.

Przeżywa długie pętle

Pojedyncze wywołanie prawie nie zauważa słabej tożsamości. Agent wykonujący dwadzieścia wywołań narzędzi — zauważa. Każda iteracja to okazja do dryfu: do przyjęcia ramy ostatniego wyniku narzędzia zamiast ramy zadania. Silna tożsamość jest potwierdzana przy każdym pojedynczym zapytaniu, bo system prompt jest przy każdym pojedynczym zapytaniu wysyłany od nowa. Właśnie ta właściwość sprawia, że dryf jest opanowywalny — i właśnie ona ma swoją cenę.

Czyni agenta testowalnym

Tożsamość z jawną definicją ukończenia to kontrakt, dla którego można napisać asercje. "Każdy zmieniony plik pojawia się dokładnie raz" jest sprawdzalne. "Bądź dokładny" — nie.

To w niej żyje granica bezpieczeństwa

Claude nie zna Twojej polityki zatwierdzania. Zna ją Twój harness. Tożsamość plus świadomie wąska powierzchnia narzędzi to sposób, w jaki wyrażasz tę granicę: akcje trudno odwracalne dostają dedykowane, kontrolowalne narzędzia, a nie ogólny shell.

Cena tożsamości: tokeny

To ta mechanika, która zaskakuje osoby przechodzące z pojedynczych wywołań na agentów:

System prompt i definicje narzędzi są wysyłane ponownie przy każdym zapytaniu w pętli.

Przebieg agenta to nie jedno wywołanie API. To N wywołań, gdzie N to liczba round-tripów narzędziowych, a każde z nich niesie pełną tożsamość, pełny zestaw schematów narzędzi i całą dotychczasową konwersację.

Weźmy realistyczny setup:

KomponentTokeny
Tożsamość (system prompt)1 500
Definicje narzędzi (6 narzędzi)800
Stały prefiks na zapytanie2 300

Agent wykonujący 20 wywołań narzędzi płaci więc za ten prefiks 20 razy: 46 000 tokenów wejściowych, zanim doliczymy choć jedną linię właściwej treści zadania. Przy cenach wejścia Claude Opus 5 (5 $ / 1 mln tokenów) to około 0,23 $ na przebieg tylko za to, żeby agent wciąż przedstawiał się sam sobie — a przy 10 000 przebiegów miesięcznie: 2 300 $.

To ta liczba, po której ludzie zaczynają skracać system prompty. Nie rób tego. Zacache'uj je.

Prompt caching — jak tożsamość staje się prawie darmowa

Prompt caching zamienia ten stały prefiks z kosztu na każde zapytanie w koszt bliski zeru. Wszystkim rządzi jedna niezmiennik:

Cache to dopasowanie prefiksu. Zmiana choćby jednego bajtu gdziekolwiek w prefiksie unieważnia wszystko, co jest za nim.

Kolejność renderowania to tools → system → messages. Breakpoint cache na ostatnim bloku system obejmuje więc narzędzia i tożsamość razem — dokładnie te 2 300 tokenów powyżej.

var response = await client.Messages.Create(new MessageCreateParams
{
    Model = "claude-opus-5",
    MaxTokens = 16000,
    System = new List<TextBlockParam>
    {
        new()
        {
            Text = ReleaseAuditorIdentity,          // bajt w bajt identyczny w każdym zapytaniu
            CacheControl = new CacheControlEphemeral(),  // domyślnie TTL 5 minut
        },
    },
    Messages = messages,
});

// Zawsze weryfikuj — cache zawodzi po cichu, nigdy głośno
Console.WriteLine($"zapisane:    {response.Usage.CacheCreationInputTokens}");
Console.WriteLine($"odczytane:   {response.Usage.CacheReadInputTokens}");
Console.WriteLine($"pełna cena:  {response.Usage.InputTokens}");

Ekonomia: odczyt z cache kosztuje około 0,1× bazowej ceny wejścia, zapis do cache 1,25× przy domyślnym TTL 5 minut (albo 2× przy TTL 1 godziny). Zastosowane do tego samego przebiegu z 20 iteracjami:

ScenariuszEfektywne tokeny wejścioweKoszt (Opus 5)
Bez cache (20 × 2 300)46 0000,230 $
Z cache (1 zapis + 19 odczytów)~7 2500,036 $

84% mniej na tożsamościowej części rachunku, bez zmiany samego promptu. Break-even przychodzi trywialnie szybko: przy TTL 5 minut już dwa zapytania spłacają narzut zapisu.

Jeden szczegół warto znać: minimalny cache'owalny prefiks zależy od modelu i nie jest monotoniczny między generacjami — 512 tokenów w Claude Opus 5, 1 024 w Sonnet 5, 4 096 w Haiku 4.5. Tożsamość o długości 3 000 tokenów zacache'uje się na Opus 5, a na Haiku 4.5 po cichu nie. Bez błędu, po prostu cache_creation_input_tokens: 0.

Cisi zabójcy cache

Tu wycieka realna gotówka. Każdy z tych wzorców wygląda niewinnie na code review:

WzorzecDlaczego rachunek się podwaja
DateTime.Now wstrzyknięte w system promptPrefiks zmienia się przy każdym zapytaniu — nic się nigdy nie cache'uje
ID użytkownika lub sesji w tożsamościOsobny wpis cache na użytkownika; zero współdzielenia
Warunkowe sekcje tożsamości (if (isPremium) system += ...)Każda kombinacja flag to inny prefiks
Lista narzędzi budowana per użytkownik lub per zapytanieNarzędzia renderują się na pozycji 0 — cały cache umiera
Niedeterministyczna serializacja JSON schematów narzędziInna kolejność bajtów → inny prefiks
Zmiana modelu w trakcie konwersacjiCache jest przypisany do modelu

Rozwiązanie jest architektoniczne, a nie kwestią rozmieszczenia markerów: zamroź tożsamość i wypchnij wszystko zmienne na koniec promptu.

Kiedy instrukcja operatora naprawdę musi dotrzeć w środku konwersacji — przełączenie trybu, świeżo wstrzyknięty stan — nie edytuj system promptu na poziomie żądania. Na Claude Opus 5, Opus 4.8 i Fable 5 możesz zamiast tego dopisać wiadomość { "role": "system" } do tablicy messages. Siedzi ona za zacache'owaną historią, więc prefiks przeżywa — a w odróżnieniu od tekstu przemyconego w turze użytkownika jest niepodrabialnym kanałem operatora.

Jeden agent-monolit czy zespół specjalistów?

Kiedy zaakceptujesz, że tożsamość jest cache'owana, rachunek się zmienia. Wąski agent nie jest już droższy od szerokiego — a jest wymiernie lepszy:

WymiarJeden agent-generalistaZespół specjalistów
Rozmiar promptu na zapytanieDuży (wszystkie reguły do wszystkich zadań)Mały (tylko istotne reguły)
Skuteczność cacheNiska — prompt przesuwa się per typ zadaniaWysoka — każda tożsamość jest zamrożona
Zanieczyszczenie kontekstuWszystko ląduje w jednym oknieCzytanie zostaje w subagencie
Wybór modeluJeden model do wszystkiegoTani do czytania, mocny do oceny
Diagnoza awarii"Prompt się pogorszył"Izolowana do jednego agenta

Wiersz o zanieczyszczeniu kontekstu jest w praktyce najważniejszy. Podzadanie, które czyta dwadzieścia plików, nie musi zostawiać zawartości dwudziestu plików w oknie głównego agenta na zawsze. Zdeleguj je, a główna pętla dostanie wniosek zamiast surowca.

Wybór modelu wzmacnia ten efekt:

ModelID modeluWejście $/1 mlnWyjście $/1 mln
Claude Fable 5claude-fable-510,00 $50,00 $
Claude Opus 5claude-opus-55,00 $25,00 $
Claude Sonnet 5claude-sonnet-53,00 $15,00 $
Claude Haiku 4.5claude-haiku-4-51,00 $5,00 $

Podzadania z dużą ilością czytania i małą dawką oceny kosztują na Haiku 4.5 jedną piątą Opus 5 za token wejściowy. Ale uwaga na ograniczenie z poprzedniej sekcji: nie przełączaj modeli wewnątrz jednej konwersacji, żeby złapać tę oszczędność — cache jest przypisany do modelu i zapłacisz więcej, niż zaoszczędzisz. Zamiast tego uruchom subagenta na tańszym modelu, a główną pętlę trzymaj na jednym modelu.

Dwie kolejne dźwignie, obie dostępne na aktualnych modelach:

  • Effort (output_config.effort, od low do max) steruje głębokością myślenia i ogólną rozlewnością. Niższy effort oznacza mniej, ale bardziej skonsolidowanych wywołań narzędzi i mniej wstępu — często najlepsza pojedyncza dźwignia kosztowa dla subagentów i rutynowej pracy.

  • Context editing i compaction nie pozwalają długim przebiegom puchnąć: editing usuwa nieaktualne wyniki narzędzi, compaction streszcza wcześniejszą historię po stronie serwera, gdy zbliżasz się do okna kontekstu.

Praktyczny budżet tokenów

Dla powyższego agenta-audytora release'u, 20 wywołań narzędzi na średniej wielkości diffie:

PozycjaTokenyUwagi
Tożsamość + narzędzia (cache)~7 250 efektywnie1 zapis + 19 odczytów
Wyniki narzędzi (diff, odczyty plików)~60 000Prawdziwy sprawca — przycinaj
Rosnąca historia konwersacji~35 000 efektywnieCache'owana przyrostowo per tura
Wyjście (znaleziska, uzasadnienia)~8 000Rozliczane 5× drożej niż wejście

Wniosek z tej tabeli jest taki, jakiego nikt się nie spodziewa: po zacache'owaniu tożsamość jest najtańszą rzeczą w całym przebiegu. Drogie są niefiltrowane wyniki narzędzi i tokeny wyjściowe. Co oznacza, że odruch skracania system promptu w celu oszczędności jest dokładnie odwrotny do właściwego — dłuższa, ostrzejsza tożsamość, która powstrzyma agenta od przeczytania trzech niepotrzebnych plików, zwraca się wielokrotnie.

Podsumowanie

Sześć zasad, które stosuję teraz do każdego budowanego agenta:

  1. Pisz tożsamość jako artefakt, nie literał stringa. Zakres, granica narzędzi, format wyjścia, definicja ukończenia. Wersjonuj, przeglądaj, testuj.

  2. Przyjmij, że jest wysyłana ponownie przy każdym zapytaniu — bo jest. To dzięki temu działa i dlatego kosztuje.

  3. Cache'uj prefiks i weryfikuj cache. Jeśli cache_read_input_tokens wynosi zero w kolejnych zapytaniach, coś go unieważnia. Znajdź to.

  4. Zamroź prefiks, zmienne na koniec. Żadnych znaczników czasu, ID użytkowników, sekcji warunkowych ani zestawów narzędzi per zapytanie.

  5. Kilka wąskich agentów bije jednego szerokiego. Lepsze cache, izolowany kontekst, izolowane awarie, tańszy dobór modelu per podzadanie.

  6. Optymalizuj wyniki narzędzi, zanim zaczniesz optymalizować prompt. Tam naprawdę są tokeny.

Nadanie agentowi tożsamości to nie odgrywanie roli i nie dekoracja. To kontrakt interfejsu między Twoim systemem a komponentem niedeterministycznym — a kiedy jest zacache'owany, to również najtańsza niezawodność, jaką możesz kupić.

Uwaga: wszystkie liczby tokenów i koszty powyżej to szacunki rzędu wielkości z moich własnych przebiegów. Przed budżetowaniem zmierz własne przy pomocy endpointu do liczenia tokenów.

Porozmawiajmy o planowanym projekcie

Pierwsza konsultacja jest bezpłatna i niezobowiązująca. Wystarczy krótki opis procesu oraz oczekiwanego rezultatu.

Porozmawiajmy o projekcie