Agent wybiera złe narzędzie

przez Łukasz | sie 24, 2026

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 losowego szumu: mylą się te same przypadki. Nie co dwudziesty losowy, tylko konkretne sformułowania, konsekwentnie, przy każdym przebiegu.

Drugi sygnał: trafność spadła po tym, jak ktoś dodał narzędzia — również te niezwiązane z mylonymi.

Najpierw ustal, która to awaria

To są trzy różne rzeczy, mylone ze sobą i wymagające innych napraw. Zanim pójdziesz dalej, sprawdź w śladzie, która występuje.

A — nie wybrał żadnego narzędzia. Model odpowiedział z siebie, mimo że powinien sprawdzić. W śladzie nie ma wywołania.

B — wybrał niewłaściwe narzędzie. Wywołanie jest, narzędzie nie to.

C — wybrał właściwe, źle wypełnił argumenty. Narzędzie się zgadza, wartości nie.

Każda ma inny zestaw przyczyn i inną naprawę. Mieszanie ich to najczęstszy powód, dla którego „poprawiliśmy opisy i nic to nie dało”.

Mechanizm w trzech zdaniach

Model nie widzi twojego kodu — widzi wyłącznie definicję narzędzia: nazwę, opis i schemat parametrów. Wybór jest zwykłą predykcją opartą na tym tekście, a nie metodycznym przeglądem listy.

Model waży wszystkie opisy naraz, więc opisy podobne realnie ze sobą konkurują — i to jest źródło większości pomyłek.

Diagnostyka różnicowa

Dla awarii A — brak wywołania

A1. Narzędzia nie ma w katalogu w tym kroku. Najbardziej banalna przyczyna i zaskakująco częsta przy ładowaniu warunkowym. Sprawdź, co realnie poszło do modelu w tym obrocie, a nie co jest zdefiniowane w kodzie.

A2. Model zna odpowiedź z treningu. Pytanie o coś ogólnego — stawki VAT, definicję, format daty — nie wygląda dla modelu na wymagające sprawdzenia. Rozpoznanie: odpowiedź jest merytorycznie sensowna, tylko nieoparta na twoich danych.

A3. Nic nie mówi, że ma używać narzędzi. Prompt systemowy opisuje rolę, ale nie zawiera zdania „przy pytaniach o dane klienta zawsze sprawdź w systemie”. Model nie zakłada tego sam.

Dla awarii B — złe narzędzie

B1. Opisy konkurują. Dwa narzędzia z tego samego obszaru, oba opisane wyłącznie przez to, co robią, żadne przez to, kiedy go nie używać. Najczęstsza przyczyna w całym syndromie.

Test: przeczytaj oba opisy, udając, że nie znasz systemu. Czy da się jednoznacznie rozstrzygnąć mylony przypadek? Jeśli wahasz się ty, model też.

B2. Nazwa odzwierciedla strukturę kodu. get_data, crm_query, api_v2 — nazwa niesie najwięcej informacji i jest widziana pierwsza. Jeśli nie mówi, co narzędzie robi z punktu widzenia zadania, opis musi nadrabiać.

B3. Przeciążenie katalogu. Trafność spada wraz z liczbą narzędzi, najmocniej przy pokrewnych. Rozpoznanie jest łatwe: zmierz trafność na tym samym zestawie zapytań przy pełnym katalogu i przy dwóch narzędziach docelowych. Jeśli różnica jest duża, to przeciążenie, nie opisy.

B4. Kontekst z poprzednich kroków ciągnie w złą stronę. Wynik wcześniejszego narzędzia zawierał treść sugerującą inną drogę. Rozpoznanie: pomyłka pojawia się dopiero od któregoś kroku, przy pierwszym wywołaniu wybór jest poprawny.

Dla awarii C — złe argumenty

C1. Format nie jest podany w opisie pola. Model zgaduje konwencję twojego systemu. Jeśli opis brzmi „numer zamówienia” zamiast „numer zamówienia w formacie ZAM-0000″, zgadywanie jest jedyną opcją.

C2. Wartości dopuszczalne opisane prozą zamiast w schemacie. Jeśli pole przyjmuje jedną z pięciu wartości, a lista jest w opisie tekstowym, model może wpisać szóstą. W schemacie — nie może.

C3. Wartość jest zmyślona. Numer, którego nigdzie nie było, wygenerowany bo pasował do formatu. To już halucynacjaw argumencie i naprawia się ją walidacją istnienia, nie opisem.

Przecinająca wszystkie trzy

Losowość na kroku wyboru. Jeśli wywołania decydujące o narzędziu idą z wysoką temperaturą, część rozstrzygnięć wypada przypadkiem. Rozpoznanie: uruchom ten sam przypadek pięć razy. Różne wyniki przy identycznym wejściu oznaczają, że problemem jest ustawienie samplingu, a nie opis.

Postępowanie

Najpierw zbuduj zestaw testowy. Kilkanaście realnych zapytań z zapisanym oczekiwanym narzędziem. Bez tego każda poprawka jest zgadywaniem, a poprawa opisu jednego narzędzia potrafi popsuć wybór innego.

Potem, zależnie od rozpoznania: dla B1 — granice negatywne w opisach, czyli zdanie „nie używaj, gdy…, wtedy użyj X”. Dla B3 — ograniczenie katalogu. Dla C1 i C2 — formaty w opisach pól i wartości dopuszczalne w schemacie. Dla A3 — jawna reguła w prompcie systemowym. Dla C3 — walidacja istnienia przed wykonaniem.

Ustaw niską losowość na krokach wyboru narzędzia. To osobna decyzja od ustawień dla kroków piszących tekst dla człowieka i warto ją podjąć świadomie.

Nie zaczynaj od zmiany modelu. Mocniejszy model podnosi trafność o kilka punktów i maskuje przyczynę, która wróci przy pierwszym trudniejszym przypadku — a kosztuje wielokrotnie więcej niż poprawienie trzech zdań w opisie.

Profilaktyka

Zestaw zapytań uruchamiany przy każdej zmianie katalogu narzędzi i przy każdej zmianie modelu. Pomiar przed i po — nie wrażenie, że jest lepiej.

Logowanie wybranego narzędzia razem z pytaniem, żeby dało się później zbudować zestaw z realnych przypadków zamiast wymyślonych.

Jak zdiagnozować u siebie

Miernik trafności z macierzą pomyłek — pokazuje nie tylko ile, ale które narzędzie jest mylone z którym. To jest informacja, która wprost wskazuje parę opisów do poprawienia.

python
from collections import Counter
from openai import OpenAI

client = OpenAI()

przypadki = [
    ("Gdzie jest zamówienie ZAM-4471?",          "status_zamowienia"),
    ("Co zamawiał klient KL-0012?",              "szukaj_zamowien"),
    ("Czy ZAM-9001 wysłane?",                    "status_zamowienia"),
    ("Pokaż zamówienia klienta KL-0300.",        "szukaj_zamowien"),
    ("Klient KL-0012 pyta o zakupy.",            "szukaj_zamowien"),
    ("Sprawdź ZAM-1234.",                        "status_zamowienia"),
    ("Ile kosztuje wysyłka do Niemiec?",         "brak"),
]

def zmierz(narzedzia, powtorzenia=3, temperatura=0):
    pomylki, trafienia, razem = Counter(), 0, 0
    for pytanie, oczekiwane in przypadki:
        for _ in range(powtorzenia):
            odp = client.chat.completions.create(
                model="gpt-4o-mini",
                messages=[{"role": "user", "content": pytanie}],
                tools=narzedzia, temperature=temperatura,
            ).choices[0].message
            wybrane = odp.tool_calls[0].function.name if odp.tool_calls else "brak"
            razem += 1
            if wybrane == oczekiwane:
                trafienia += 1
            else:
                pomylki[(oczekiwane, wybrane)] += 1

    print(f"trafność: {trafienia}/{razem} ({trafienia/razem:.0%})")
    for (ocz, wyb), n in pomylki.most_common():
        etykieta = "BRAK WYWOŁANIA (awaria A)" if wyb == "brak" else f"wybrano {wyb}"
        print(f"  {n}x  oczekiwano {ocz} → {etykieta}")

Trzy powtórzenia na przypadek są tu istotne: przy jednym przebiegu nie odróżnisz błędu systematycznego od losowego. Jeśli ta sama para myli się we wszystkich trzech, to opisy. Jeśli raz na trzy — to sampling.

Wywołaj zmierz dwa razy: z pełnym katalogiem i z samymi narzędziami docelowymi. Różnica jest miarą przeciążenia. Potem raz z temperaturą podniesioną — różnica jest miarą wpływu losowości.

Ćwiczenie: dopisz do zestawu przypadek, o którym wiesz, że modelowi się myli, i sprawdź, czy macierz pokazuje go jako powtarzalną parę. Jeśli tak, masz dokładnie dwa opisy do poprawienia — i nie musisz ruszać reszty katalogu.

Powiązane

Jak pisać definicje i ile narzędzi pokazywać: Maszyneria agenta. Dlaczego wybór jest predykcją, a nie decyzją: Anatomia LLM.

Następny syndrom: Działał wczoraj, dziś nie działa.

Model nie pamięta — pamięta produkt

Model nie pamięta — pamięta produkt

Model nie pamięta ani jednego słowa z waszej poprzedniej wymiany. Wagi są zamrożone, między turami nie zapisuje się nic, a wrażenie ciągłości powstaje przez mechanizm tak prosty, że po jego poznaniu przestaje dziwić połowa rzeczy z tej serii — łącznie z rachunkiem za...

Czego nie widzisz w oknie czatu

Czego nie widzisz w oknie czatu

Okno czatu wygląda jak najkrótsza możliwa droga do modelu, a jest najdłuższą. Między twoim zdaniem a wagami stoi więcej warstw niż w wywołaniu API — i żadnej z nich nie widzisz, nie ustawiasz i nie możesz wyłączyć. W poprzednim torze rozkładaliśmy to, co dzieje się na...