vge-promptguard-v2h: koniec ery dotrenowania w modelach detekcyjnych
Punkt wyjścia
vge-promptguard-v1g to nasz produkcyjny detektor prompt injection: encoder oparty na DeBERTa, działający dobrze na klasycznych atakach (jailbreaki, instruction override, role-play attacks).
W ciągu ostatnich miesięcy w produkcji zaczęły dominować dwa typy inputów, których v1g nie widział w treningu. Po pierwsze, outputy narzędzi agentowych: tool call results, logi, JSON-owe diffy, zrzuty z MCP serverów. v1g klasyfikował je jako atak, bo formalnie wyglądały jak instrukcje. Po drugie, polskie meta-rozmowy o bezpieczeństwie: pytania użytkowników w stylu „jak działa prompt injection", treści edukacyjne, fragmenty naszej własnej dokumentacji. Te v1g też brał za atak.
Dodatkowo pojawiły się nowe wektory ataku (m.in. ASCII smuggling, indirect injection przez RAG, multi-turn priming), których v1g po prostu nie znał.
Pierwszy plan: dotrenować v1g na nowych danych. Po sześciu tygodniach prób porzuciliśmy go całkowicie.

Dlaczego dotrenowanie v1g się nie udało
Przeszliśmy przez standardową bibliotekę technik anty-catastrophic-forgetting: różne harmonogramy LR (cosine, warmup-decay, layer-wise LR decay), regularyzacja R-Drop i EWC, distylacja wiedzy z v1g jako teacher (KL na logitach), LoRA z zamrożoną bazą (rank 8, 16, 32), uśrednianie wag wielu seedów (SWA, model soup po 5 i 10 runach), blendy w przestrzeni parametrów (linear interpolation v1g i fine-tuned), targeted oversampling klas, na których v1g był słaby.
W każdej konfiguracji obserwowaliśmy ten sam wzorzec: poprawa na nowej dystrybucji o 4 do 11 punktów F1 oznaczała spadek na starej dystrybucji o 2 do 7 punktów F1. Najlepsze model soupy zmniejszały regresję, ale nie do zera.
Powód jest geometryczny. Optimum dla starej dystrybucji (v1g) i optimum dla nowej dystrybucji leżą w różnych basenach funkcji straty. Średnia ważona wag z dwóch basenów daje punkt w „dolinie" między nimi, a nie w żadnym z nich. Stąd model soup pomaga marginalnie, ale nie rozwiązuje problemu.
Wniosek operacyjny: jeden zestaw wag DeBERTa, dotrenowany na obu dystrybucjach naraz, nie utrzymuje pełnej kompetencji v1g.
Architektura vge-promptguard-v2h
v2h to dwa modele i jeden router decyzyjny.
v1g (base). Bez zmian. Produkcyjny model, traktowany jako strażnik kompetencji na klasycznych atakach.
h_model (support). Ten sam encoder co v1g, fine-tuned z LoRA rank 16 na nowej dystrybucji (agent outputy, polskie meta-rozmowy, nowe wektory ataku). Ustabilizowany uśrednieniem 5 niezależnych runów ze SWA. Nie zastępuje v1g, uzupełnia jego pole widzenia.
Router. Czysty kod, brak parametrów uczonych gradientem. Dostaje na wejściu: confidence score z v1g, confidence score z h_model, raw text inputu. Zwraca finalną etykietę (attack / benign).
Reguła routera
Router ma trzy gałęzie.
1. Default to v1g. Jeśli żaden z warunków poniżej nie jest spełniony, router zwraca decyzję v1g. To zachowanie domyślne dla większości ruchu i powód, dla którego v2h nie regresuje na starej dystrybucji.
2. h_model override w stronę benign. Aktywuje się, gdy h_model ma confidence_benign > 0.92 oraz v1g ma confidence_attack < 0.85. Pierwszy próg gwarantuje, że h_model nie nadpisze v1g „na słabym sygnale". Drugi próg gwarantuje, że h_model nigdy nie zagłuszy bardzo pewnej detekcji v1g.
3. h_model add attack. Aktywuje się, gdy h_model ma confidence_attack > 0.80 a v1g zwrócił benign. Próg jest niższy niż dla override, bo dodawanie czujności kosztuje fałszywe alarmy, a nie pominięte ataki.
W strefie pośredniej (h_model bez silnego sygnału) głos h_model nie wchodzi do decyzji.
Konsekwencja praktyczna: na audycie pojedynczej decyzji widać dokładnie, który model ją podjął i dlaczego. Dwa scory, jedna reguła, brak ukrytej meta-warstwy.
Druga warstwa: pattern-aware kalibracja
Po pierwszym tygodniu produkcji zauważyliśmy konkretną klasę inputów, na której v1g zwracał confidence_attack > 0.95, a były to autentyczne agent tool outputy: JSON-owe odpowiedzi z MCP serverów i fragmenty pythonowych tracebacków. Globalne obniżenie progu w gałęzi 2 routera załatwiłoby ten przypadek, ale przepuściłoby też część prawdziwych ataków formatowanych jako pseudo-JSON.
Rozwiązanie: lekki regex/heurystyczny detektor wzorca (35 linii kodu), który rozpoznaje wyraźne sygnatury tool output (struktura JSON o znanych kluczach, nagłówki HTTP, pythonowy traceback). Jeśli wzorzec matchuje, router używa progów { override 0.85, add 0.70 } zamiast standardowych { 0.92, 0.80 }.
Detektor wzorca nie patrzy na semantykę inputu, tylko na cechy powierzchniowe. Każdą jego regułę można pokazać klientowi w audycie. Świadomie nie obejmuje tekstów wolnoformowych, gdzie atak mógłby być ukryty kontekstowo, więc relaksacja progów dotyczy tylko wąskiego, jednoznacznie rozpoznawalnego ruchu.
Wyniki
Mierzone na trzymanym test secie złożonym ze starej dystrybucji v1g (12k przykładów) i nowej dystrybucji (8k przykładów).
v2h kosztuje dwa przejścia encoder zamiast jednego. Detektor wzorca dorzuca poniżej 1 ms.
| Metryka | v1g | v1g po fine-tune | v2h |
|---|---|---|---|
| F1 stara dystrybucja | 0.947 | 0.891 | 0.946 |
| F1 nowa dystrybucja | 0.612 | 0.864 | 0.873 |
| Latencja p50 | 18 ms | 18 ms | 34 ms |
| Latencja p99 | 41 ms | 41 ms | 78 ms |
Co to oznacza dla dalszej roadmapy
Architektura jest rozszerzalna z założenia. Każdą nową powierzchnię ataku, nowy język albo nowe środowisko narzędziowe można obsłużyć dorzucając kolejnego eksperta i kolejną gałąź w routerze, bez tykania v1g i bez ryzyka regresji na starej dystrybucji. To kierunek, w którym będziemy rozwijać vge-promptguard w kolejnych wersjach.
Dostępność
vge-promptguard-v2h nie pojawi się na razie na Hugging Face. Model v1g zebrał tam zauważalne zainteresowanie ze strony kilku konkurencyjnych zespołów, a v2h zawiera istotnie więcej naszego IP: konstrukcję routera, kalibrację progów, pattern detector, dane treningowe h_modelu. Nie zamierzamy ułatwiać szybkiego skopiowania nowej architektury.
v2h trafi do produkcji w najbliższym wydaniu Vigil Guard Enterprise 1.7.x, które udostępnimy wkrótce.