Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds
Powrót do kolekcji
Przewodnik11 min czytania

Promptfoo, testy i red teaming aplikacji z LLM

Promptfoo testuje prompty, modele i agentów oraz generuje ataki sprawdzające odporność. Konfiguracja, asercje, przejęcie przez OpenAI, ceny i praca w CI.

Promptfoo, testy dla rzeczy, których nie da się przetestować zwykle

Kod testuje się asercjami, bo wynik jest deterministyczny. Odpowiedź modelu deterministyczna nie jest, więc pytanie „czy ta zmiana promptu coś poprawiła" zwykle kończy się sprawdzeniem trzech przykładów i wrażeniem, że jest lepiej.

Promptfoo zamienia to wrażenie w liczbę. Definiujesz przypadki testowe, opisujesz, co ma być spełnione, i uruchamiasz porównanie wielu wariantów naraz: różnych promptów, różnych modeli, różnych ustawień. Drugą częścią narzędzia jest generowanie ataków sprawdzających, czy aplikacja da się złamać.

W marcu 2026 roku OpenAI ogłosiło przejęcie projektu, z zapewnieniem, że pozostanie otwarty na dotychczasowej licencji, a technologia trafi do platformy tego dostawcy. Dla użytkowników wersji otwartej nic się nie zmieniło.

Pierwszy zestaw testów

Konfiguracja żyje w pliku, więc podlega kontroli wersji jak reszta kodu.

Code
Bash
npx promptfoo@latest init
Code
YAML
prompts:
  - "Sklasyfikuj zgloszenie do kategorii: {{tresc}}"
  - file://prompty/klasyfikacja-v2.txt

providers:
  - openai:gpt-5-mini
  - anthropic:claude-sonnet-5

tests:
  - vars:
      tresc: "Nie moge sie zalogowac od wczoraj"
    assert:
      - type: contains
        value: "logowanie"
      - type: latency
        threshold: 3000

  - vars:
      tresc: "Prosze o duplikat faktury za marzec"
    assert:
      - type: contains
        value: "platnosci"

Uruchomienie porównuje każdy prompt z każdym modelem na każdym przypadku, więc dwa prompty i dwa modele przy dwóch przypadkach dają osiem wywołań. Wynik pokazuje się w tabeli, gdzie od razu widać, który wariant przechodzi więcej testów.

Ta konstrukcja jest sednem narzędzia. Zamiast poprawiać jeden prompt w kółko, porównujesz kilka wariantów naraz na tym samym zestawie i wybierasz ten, który wypada najlepiej według miary, a nie według wrażenia.

Rodzaje asercji

Asercje dzielą się na trzy grupy o różnym koszcie i różnej wiarygodności, a mieszanie ich bez rozeznania to najczęstszy błąd.

Asercje deterministyczne sprawdzają fakty o odpowiedzi: czy zawiera dany ciąg, czy pasuje do wyrażenia, czy jest poprawnym JSON-em, czy mieści się w limicie czasu i kosztu. Są darmowe, natychmiastowe i powinny stanowić większość zestawu.

Code
YAML
assert:
  - type: is-json
    value:
      required: [kategoria, priorytet]
  - type: javascript
    value: "output.priorytet >= 1 && output.priorytet <= 5"
  - type: cost
    threshold: 0.01

Asercje oparte o model sprawdzają rzeczy nieporównywalne wprost: czy odpowiedź trzyma się podanych faktów, czy ma właściwy ton, czy nie obiecuje rzeczy zabronionych. Kosztują tokeny i wprowadzają własny szum, więc rezerwuj je do tego, czego nie da się sprawdzić prościej.

Code
YAML
assert:
  - type: llm-rubric
    value: "Odpowiedz opiera sie wylacznie na podanym kontekscie i nie dodaje faktow"
  - type: factuality
    value: "Duplikat faktury pobiera sie z panelu rozliczen"

Trzecia grupa to asercje porównujące z odpowiedzią wzorcową, przydatne, gdy masz przygotowane wzorce. Są wiarygodniejsze od oceny swobodnej, ale wymagają pracy przy tworzeniu zestawu.

Red teaming

Druga połowa narzędzia sprawdza, czy aplikację da się zmusić do zachowania, którego nie chcesz. To rzecz, którą trudno zrobić ręcznie, bo wymaga pomysłowości i systematyczności naraz.

Code
Bash
npx promptfoo@latest redteam init
npx promptfoo@latest redteam run

Narzędzie generuje próby ataku w kilku kategoriach. Wstrzyknięcie promptu sprawdza, czy treść od użytkownika potrafi nadpisać instrukcję systemową. Obejście zabezpieczeń szuka sformułowań, przy których model robi to, czego miał odmówić. Wyciek danych sprawdza, czy da się wydobyć treść instrukcji systemowej albo dane innego użytkownika. Nadużycie narzędzi sprawdza, czy agenta da się skłonić do wywołania operacji poza zakresem.

Wynikiem jest raport z konkretnymi zapytaniami, które zadziałały. To ważne, bo lista podatności bez przykładu jest bezużyteczna, a zapytanie, które faktycznie przeszło, można wprost dopisać do zestawu testowego jako przypadek regresyjny.

Warto uruchamiać to przed wydaniem, a nie po incydencie. Aplikacja z agentem mającym dostęp do zapisu jest tu szczególnym przypadkiem, bo skutki udanego ataku wykraczają poza nieodpowiednią odpowiedź.

Testowanie całej ścieżki, nie samego promptu

Najczęstszy błąd metodyczny polega na testowaniu instrukcji w oderwaniu od reszty aplikacji. Prompt z wpisanym na sztywno kontekstem przechodzi testy, a aplikacja odpowiada źle, bo problem leży w tym, jakie fragmenty trafiają do kontekstu.

Narzędzie potrafi odpytywać własny punkt końcowy, więc testujesz to, co faktycznie działa u użytkownika.

Code
YAML
providers:
  - id: https://localhost:3000/api/assystent
    config:
      method: POST
      headers:
        Content-Type: application/json
      body:
        pytanie: "{{tresc}}"
        userId: "test-118"
      transformResponse: json.odpowiedz

Przy takim układzie test obejmuje wyszukiwanie w bazie wektorowej, wywołania narzędzi i całą logikę pośrednią. Jeśli aplikacja pobiera fragmenty z Chromy albo z rozszerzenia pgvector, to właśnie ten etap odpowiada zwykle za większość złych odpowiedzi, a nie sformułowanie instrukcji.

Osobno warto testować sam etap wyszukiwania. Zestaw pytań z zaznaczonym fragmentem, który powinien się znaleźć w kontekście, pozwala zmierzyć trafność wyszukiwania niezależnie od jakości odpowiedzi. To rozdziela dwa problemy, które bez takiego podziału mieszają się ze sobą.

Praca zespołowa i przegląd wyników

Wyniki testów w terminalu są wygodne dla jednej osoby i bezużyteczne dla zespołu. Narzędzie udostępnia widok przeglądarkowy z tabelą porównawczą, gdzie widać odpowiedzi obok siebie.

Code
Bash
npx promptfoo@latest view

Ten widok przydaje się szczególnie przy ocenie ręcznej. Część rzeczy trudno zapisać jako asercję, a łatwo ocenić wzrokiem, więc przejrzenie dwudziestu odpowiedzi w tabeli zajmuje kwadrans i mówi więcej niż liczba przechodzących testów.

Przy pracy zespołowej wartość mają też ustalone role. Osoba zmieniająca prompt uruchamia zestaw, ale ocena tego, czy zmiana jest do przyjęcia, powinna należeć do kogoś, kto zna wymagania biznesowe. To ta sama zasada co przy przeglądzie kodu.

Warto też ustalić, kto dopisuje nowe przypadki. Najlepsze źródło to zgłoszenia użytkowników i sytuacje, w których aplikacja zawiodła, więc osoba obsługująca zgłoszenia jest naturalnym kandydatem, o ile format zestawu jest na tyle prosty, żeby dało się to zrobić bez znajomości kodu.

Praca w potoku budowania

Zestaw testów uruchamiany ręcznie działa dwa tygodnie, a potem przestaje. Włączenie go do procesu budowania sprawia, że regresja wychodzi przy zmianie, a nie u użytkownika.

Code
YAML
- name: Testy promptow
  env:
    PROMPTFOO_PASS_RATE_THRESHOLD: '90'
  run: npx promptfoo@latest eval --config promptfoo.yaml

Dwie rzeczy wymagają rozstrzygnięcia przy takim wdrożeniu. Pierwsza to koszt: pełny zestaw przy każdym zapisie kodu to setki wywołań dziennie, więc rozsądny podział to mały zestaw szybki przy każdej zmianie i pełny przed wydaniem albo raz na dobę.

Druga to niedeterminizm. Test na modelu potrafi przejść cztery razy i nie przejść za piątym, więc próg zaliczenia lepiej ustawić na poziomie zestawu, niż wymagać kompletu. Służy do tego zmienna środowiskowa podana wyżej, przyjmująca odsetek zaliczonych przypadków; domyślnie wynosi sto, a polecenie kończy się kodem wyjścia sto, gdy wynik spadnie poniżej progu.

Wyniki warto przechowywać między przebiegami, bo dopiero porównanie z poprzednim uruchomieniem pokazuje kierunek. Pojedynczy wynik mówi, ile testów przeszło, a różnica mówi, czy ostatnia zmiana pomogła.

Ceny

WariantKosztCo obejmuje
Community0 USDPełne testowanie, licencja MIT, red teaming do dziesięciu tysięcy prób miesięcznie, praca lokalna albo u siebie
Enterprisewycena indywidualnaWłasne limity prób, wspólne wyniki, zarządzanie dostępem, ciągłe monitorowanie, wdrożenie w chmurze dostawcy
Enterprise On-Premisewycena indywidualnaWszystko z poprzedniego wiersza plus wdrożenie na własnej infrastrukturze i pełna izolacja danych

Cennik nie podaje żadnych kwot poza zerem: oba plany płatne wycenia się indywidualnie według wielkości zespołu. Warto natomiast znać jedyny limit wersji darmowej. Próba to pojedyncze zapytanie wysłane do sprawdzanego systemu w czasie red teamingu, a plan Community obejmuje dziesięć tysięcy prób miesięcznie bez opłaty. Dodatkowe próby kupuje się wyłącznie w ramach umowy Enterprise, więc przy większej skali testów to ten limit, a nie cena narzędzia, wyznacza moment rozmowy z handlowcem.

Sama biblioteka jest darmowa, ale testowanie kosztuje tokeny. Sto przypadków przy dwóch modelach i dwóch promptach to czterysta wywołań, więc przed uruchomieniem dużego zestawu warto policzyć, ile to będzie.

Trzy sposoby ograniczają ten koszt. Pierwszy to przewaga asercji deterministycznych, które nic nie kosztują. Drugi to testowanie na modelu tańszym tam, gdzie sprawdzasz logikę promptu, a nie jakość odpowiedzi. Trzeci to buforowanie wyników, dzięki któremu powtórne uruchomienie bez zmian nie generuje wywołań.

Co robić z wynikiem red teamingu

Raport z listą udanych ataków jest początkiem pracy, a nie jej końcem. Trzy rzeczy trzeba rozstrzygnąć przy każdej znalezionej podatności.

Pierwsza to skutek. Odpowiedź, w której model wyszedł poza temat, jest kłopotem wizerunkowym. Odpowiedź, w której agent wywołał operację zmieniającą dane cudzego konta, jest incydentem bezpieczeństwa. Ta sama technika ataku może dać oba wyniki w zależności od tego, co agent ma pod ręką.

Druga to miejsce poprawki. Wzmocnienie instrukcji systemowej pomaga częściowo i da się je obejść, bo model zawsze można namówić. Trwałe rozwiązanie leży w kodzie: sprawdzenie uprawnień w narzędziu, ograniczenie zakresu operacji, wymóg zatwierdzenia przy działaniach nieodwracalnych.

Bywa też trzecie miejsce: filtr sprawdzający wejście i wyjście modelu osobno od jego instrukcji, uruchamiany przy każdym żądaniu. Najbardziej znaną otwartą biblioteką tej klasy jest LLM Guard z Protect AI i tu potrzebne jest zastrzeżenie, bo projekt został w lipcu 2026 roku zarchiwizowany, a opiekunowie napisali wprost, że nowych wykrywaczy nie będzie. Kod nadal się instaluje i działa, natomiast wpisywanie do stosu biblioteki, która nie dostanie poprawek, jest decyzją do podjęcia świadomie. Sam filtr traktuj zresztą jako warstwę zmniejszającą liczbę udanych prób, a nie jako zamiennik sprawdzenia uprawnień w narzędziu.

Trzecia to zapis w zestawie. Zapytanie, które przeszło, dopisujesz jako przypadek regresyjny, żeby przy kolejnej zmianie promptu ta sama dziura nie wróciła. Bez tego kroku poprawka żyje do najbliższej większej zmiany.

Warto też pamiętać, że red teaming automatyczny sprawdza wzorce znane narzędziu. Nie zastąpi przeglądu tego, co agent w ogóle może zrobić, a to pytanie warto zadać, zanim ktokolwiek zacznie testować. Agent bez dostępu do operacji zmieniających dane jest odporny na całą kategorię problemów z definicji.

Promptfoo kontra alternatywy

NarzędzieMocna stronaSłabośćKiedy wybrać
PromptfooTesty i red teaming w jednym, konfiguracja w plikuBrak śladów z produkcjiPorównywanie wariantów, testy przed wydaniem
LangSmithŚlady z produkcji plus ocenyZamknięte źródło, brak red teaminguDiagnozowanie działającej aplikacji
LangfuseOtwarte źródło, wdrożenie u siebieMniej gotowych asercjiObserwowalność we własnej infrastrukturze
DSPyOptymalizacja promptu pod metrykęWymaga zestawu i metrykiAutomatyczne dobieranie instrukcji

Te narzędzia obsługują różne etapy i najczęściej używa się dwóch naraz. To służy do porównywania wariantów przed wydaniem, narzędzie obserwacyjne do diagnozowania tego, co dzieje się na produkcji. Ślady z produkcji są zresztą najlepszym źródłem przypadków testowych, więc oba układają się w pętlę.

Ostatni wiersz to inna kategoria: zamiast porównywać warianty napisane przez człowieka, dobiera instrukcję automatycznie. Można je łączyć, używając tego narzędzia jako niezależnego sprawdzenia wyniku optymalizacji.

Warto zauważyć, że żadne z tych narzędzi nie zastępuje przemyślenia, co właściwie ma być mierzone. Zestaw testów odbija to, co uznałeś za ważne, więc jeśli zabraknie w nim przypadków, na których aplikacja realnie zawodzi, wysoki wynik nie znaczy nic. To ten sam problem co przy pokryciu testami w zwykłym kodzie: liczba rośnie, a błędy zostają.

Typowe błędy

Pierwszy to zestaw złożony z przypadków łatwych. Testy, które przechodzą zawsze, nie pokazują różnicy między wariantami, a właśnie po to zestaw powstaje.

Drugi to asercje oparte o model tam, gdzie wystarczy porównanie wartości. Sprawdzenie, czy odpowiedź jest poprawnym JSON-em z wymaganymi polami, kosztuje zero, a ocena tego samego przez model kosztuje tokeny i bywa niestabilna.

Trzeci to testowanie samego promptu zamiast całej ścieżki. Jeśli aplikacja pobiera fragmenty z bazy wektorowej, test na wpisanym na sztywno kontekście nie wykryje problemu z wyszukiwaniem, który w praktyce odpowiada za większość złych odpowiedzi.

Czwarty to pominięcie red teamingu przy aplikacji przyjmującej treść od użytkowników. Wstrzyknięcie promptu nie jest zagrożeniem teoretycznym, zwłaszcza gdy agent ma dostęp do narzędzi zmieniających dane.

Piąty to uruchamianie testów wyłącznie ręcznie. Zestaw poza procesem budowania przestaje być używany w ciągu miesiąca, a wtedy regresję wykrywa użytkownik.

Szósty to wymaganie stu procent przechodzących testów. Przy odpowiedziach niedeterministycznych taki próg powoduje, że zespół zaczyna wyłączać testy zamiast poprawiać prompt.

FAQ

Czy Promptfoo jest darmowy?

Tak, wersja otwarta na licencji MIT obejmuje pełne testowanie i red teaming, a uruchamiasz ją u siebie. Plan Community jest bezpłatny na stałe, z jednym ograniczeniem: dziesięć tysięcy prób red teamingu miesięcznie. Plany Enterprise i Enterprise On-Premise wycenia się indywidualnie, bez publikowanych stawek. Płacisz natomiast za tokeny zużywane przez same testy.

Co oznacza przejęcie przez OpenAI?

W marcu 2026 roku OpenAI ogłosiło przejęcie projektu, zapowiadając, że pozostanie otwarty na dotychczasowej licencji, a obecni klienci będą nadal obsługiwani. Technologia ma trafić do platformy agentowej tego dostawcy. Dla użytkowników wersji otwartej to nie zmienia sposobu pracy, choć przy planowaniu na lata warto uwzględnić zmianę właściciela.

Czym różni się od narzędzi obserwacyjnych?

To narzędzie sprawdza warianty przed wdrożeniem, na przygotowanym zestawie przypadków. Narzędzia pokroju Langfuse zbierają ślady z działającej aplikacji i pokazują, co faktycznie się dzieje. Najlepiej działają razem: ślady dostarczają przypadków do zestawu, a zestaw pilnuje, żeby poprawka nie zepsuła czegoś innego.

Czy da się testować agentów, a nie tylko prompty?

Tak, narzędzie obsługuje też wywołania własnego punktu końcowego, więc testujesz całą ścieżkę razem z wyszukiwaniem i wywołaniami narzędzi. To zwykle sensowniejsze niż testowanie samego promptu, bo problemy najczęściej leżą w kontekście, a nie w instrukcji.

Od czego zacząć?

Od dwudziestu przypadków wziętych z prawdziwego ruchu, w tym z sytuacji, w których aplikacja zawiodła. Dodaj asercje deterministyczne, uruchom porównanie dwóch wariantów promptu i dopiero potem rozbudowuj zestaw o oceny modelem tam, gdzie prostsze sprawdzenie nie wystarcza.

Dokumentacja stoi na stronie projektu, a ogłoszenie o przejęciu opublikowano na blogu Promptfoo.