Agent czyta umowy i wypisuje ostatni dzień na wypowiedzenie. Tej daty nie ma w żadnej z nich
Data wypowiedzenia umowy nie jest polem do ekstrakcji, tylko wynikiem działania na pięciu faktach. Jak rozdzielić odczyt od rachunku w agencie.
- Zdarzenie nowy mail
- Klasyfikacja typ, pilność, klient
- Narzędzia crm_search
- Zatrzymanie odpowiedź do klienta
- Działanie mail_send
- Log wejście, decyzja, wynik
Umów ramowych w segregatorach jest 180. Zadanie dla agenta brzmi: wypisz dla każdej ostatni dzień, w którym można ją wypowiedzieć, żeby nie przedłużyła się na kolejny rok. Agent zwraca 180 dat, przy każdej wskaźnik pewności powyżej 0,9, a dwunastu z tych dat nie da się obronić. Wskaźnik tego nie pokazał, bo mierzy zupełnie co innego.
Przyczyna jest w sformułowaniu zadania, nie w modelu. Data, o którą pytasz, nie występuje w umowie. Jest wynikiem działania na czterech faktach, które trzeba odczytać osobno, i na dwóch regułach liczenia terminów z Kodeksu cywilnego. Model odczytuje. Jeśli każesz mu zwrócić gotowy wynik, policzy go i tak — tylko bez śladu, który dałoby się sprawdzić.
Agent odczytuje fakt, kalkulator liczy datę — i tylko jedno z tego ma wskaźnik pewności
Dokumentacja Azure AI Document Intelligence definiuje to wąsko: pewność pola to szacowane prawdopodobieństwo między 0 a 1, że predykcja jest poprawna, a wartość 0,95 oznacza, że predykcja jest prawdopodobnie poprawna 19 razy na 20. W tej samej dokumentacji jest zdanie, które w architekturze agenta do umów waży więcej niż sama definicja: wskaźnik na poziomie pola odzwierciedla pewność modelu co do pozycji wyodrębnionej wartości. Pozycji. Czegoś, co w dokumencie fizycznie jest.
Wartość, której w dokumencie nie było, nie ma pozycji. Nie ma więc czego oceniać, a liczba, która wraca obok takiego pola, dotyczy w najlepszym razie fragmentu, z którego model wziął dane wejściowe do rachunku. Stąd podział, od którego warto zacząć projektowanie schematu wyjściowego.
| Rodzaj pola | Przykład z umowy ramowej | Czego dotyczy wskaźnik pewności | Gdzie powstaje błąd |
|---|---|---|---|
| Przepisane | nazwa strony, NIP, data podpisania | pozycji i odczytu wartości obecnej w dokumencie | jakość skanu, dwie podobne liczby obok siebie, podpis na marginesie |
| Wyliczane | ostatni dzień na wypowiedzenie, data wygaśnięcia okresu | niczego — wartości nie było w tekście | arytmetyka terminu i reguła, według której się go liczy |
| Interpretacyjne | czy klauzula o automatycznym odnowieniu w ogóle występuje | pozycji fragmentu uznanego za tę klauzulę | wybór fragmentu, sprzeczność z aneksem, klauzula rozbita na dwa paragrafy |
Próg pewności ma sens w pierwszym wierszu i częściowo w trzecim. W drugim nie ma go na czym postawić. Jeśli w schemacie wyjściowym jest jedno pole data_wypowiedzenia, agent dostał polecenie wykonania arytmetyki po cichu — i wykona je, bez możliwości odtworzenia, skąd wziął wynik.
Pięć etykiet zamiast jednego pola: co agent ma wyjąć z umowy
Jak drobno trzeba to rozbić, pokazuje najlepiej opisany zbiór danych do przeglądu umów. CUAD, przygotowany przez The Atticus Project, zawiera 510 umów handlowych i 13 101 oznaczonych klauzul w 41 kategoriach etykiet, z 25 różnych typów umów. Autorzy podają, że każdy student prawa przed oznaczaniem przeszedł od 70 do 100 godzin szkolenia, a każda adnotacja była weryfikowana przez trzech kolejnych adnotatorów.
Istotne jest to, czego w tym zbiorze nie ma: etykiety „data wypowiedzenia”. Zamiast niej jest pięć osobnych etykiet, z których trzeba ją złożyć.
| Etykieta w CUAD | Na jakie pytanie odpowiada | Typowa pułapka przy ekstrakcji |
|---|---|---|
| Agreement Date | kiedy umowa została podpisana | bierze się ją za datę wejścia w życie, bo leży bliżej nagłówka |
| Effective Date | od kiedy umowa obowiązuje | bywa opisana warunkiem („z dniem wpłaty zaliczki”), a nie datą |
| Expiration Date | kiedy wygasa okres obowiązywania | w umowach na czas oznaczony nie jest podana wprost, tylko jako długość okresu |
| Renewal Term | na jaki okres umowa się przedłuża | inna długość niż okres pierwotny, np. 24 miesiące plus kolejne 12 |
| Notice Period To Terminate Renewal | ile wcześniej trzeba złożyć wypowiedzenie | liczone „przed końcem okresu” albo „ze skutkiem na koniec miesiąca” — dwie różne arytmetyki |
Wyniki na tym zbiorze są trzeźwiące. Najlepszy model w pracy, DeBERTa-xlarge, osiąga AUPR 47,8 proc., precyzję 44,0 proc. przy czułości 80 proc. i 17,8 proc. przy czułości 90 proc. Autorzy dodają, że wynik rozkłada się bardzo nierówno między kategoriami: dla części etykiet jest blisko pułapu 100 proc. AUPR, dla innych około 20 proc. To są wyniki modeli encoderowych z 2021 r. i dzisiejsze modele generatywne radzą sobie lepiej, ale rozrzut między łatwą a trudną kategorią nie zniknął — bo wynika z tego, jak klauzule są pisane, nie z architektury modelu. Dlatego próg pewności ustawia się per etykieta, a nie jeden dla całego dokumentu.
Ta sama klauzula o trzech miesiącach daje cztery różne daty
Weź umowę o jednym brzmieniu: podpisana 26 lutego 2026 r., wchodzi w życie 11 marca 2026 r., zawarta na 24 miesiące, przedłuża się na kolejne 12, jeżeli żadna ze stron nie wypowie jej najpóźniej trzy miesiące przed końcem okresu obowiązywania.
Koniec okresu liczy art. 112 Kodeksu cywilnego: termin oznaczony w tygodniach, miesiącach lub latach kończy się z upływem dnia, który nazwą lub datą odpowiada początkowemu dniowi terminu, a gdyby takiego dnia w ostatnim miesiącu nie było — w ostatnim dniu tego miesiąca. Na koniec terminu nakłada się druga reguła: jeżeli koniec terminu do wykonania czynności przypada na dzień uznany ustawowo za wolny od pracy lub na sobotę, termin upływa następnego dnia, który nie jest dniem wolnym od pracy ani sobotą (art. 115 k.c.). Cztery warianty, każdy wyprowadzony z tej samej klauzuli:
| Co agent odczytał i jaką regułę zastosował | Koniec okresu | Ostatni dzień na wypowiedzenie |
|---|---|---|
| Effective Date 11.03.2026 + 24 miesiące, art. 112, odliczenie trzech miesięcy wstecz | 11.03.2028 | 11.12.2027 (sobota) |
| to samo, z uwzględnieniem art. 115 k.c. | 11.03.2028 | 13.12.2027 (poniedziałek) |
| klauzula z dopiskiem „ze skutkiem na koniec miesiąca kalendarzowego” | 11.03.2028 | 30.11.2027 |
| odliczenie od Agreement Date 26.02.2026 zamiast od Effective Date | 26.02.2028 | 26.11.2027 |
Rozrzut to 17 dni. Pierwszy wariant jest po prostu zły, bo pomija art. 115. Czwarty jest zły, bo agent pomylił dwa pola, których nazwy w polskich umowach często brzmią niemal identycznie. Drugi i trzeci różnią się jedną frazą w klauzuli — i to jest różnica, którą kalkulator rozstrzyga deterministycznie, a model „na wyczucie” rozstrzyga raz tak, raz inaczej, przy tym samym wskaźniku pewności.
Osobna sprawa to pytanie, czy art. 115 k.c. stosuje się do umownego terminu liczonego przed zdarzeniem, a nie do terminu na dokonanie czynności wobec organu. W doktrynie zakres tego przepisu jest sporny — nowelizacja z 2016 r. zrównała soboty z dniami ustawowo wolnymi od pracy, ale granice stosowania przepisu wciąż bywają przedmiotem rozstrzygnięć. To nie jest pytanie do agenta ani do kalkulatora. To jest pytanie, które raz zadajesz prawnikowi, a odpowiedź zapisujesz w konfiguracji kalkulatora jako regułę z datą i podstawą.
Agent zwraca cytat i offset, kalkulator zwraca datę
Przepływ, który da się testować regresyjnie, rozdziela te dwie rzeczy twardo:
- Wejście: plik umowy plus identyfikator sprawy. Skany idą najpierw przez OCR, którego wskaźnik czyta się osobno od ekstrakcji.
- Krok 1 — ekstrakcja: agent dostaje schemat pięciu etykiet i dla każdej zwraca trzy rzeczy: dosłowny cytat, offset znakowy w pliku i wskaźnik pewności. Nie zwraca żadnej daty, której nie przepisał z dokumentu.
- Krok 2 — normalizacja: cytaty idą do parsera, który zamienia „dwudziestego szóstego lutego dwa tysiące dwudziestego szóstego roku” na datę ISO, a „24 (dwadzieścia cztery) miesiące” na liczbę. Parser albo zwraca wartość, albo odmawia — nie zgaduje.
- Krok 3 — kalkulator: zwykły kod, bez modelu. Wejście: data początkowa, długość okresu, długość okresu wypowiedzenia, reguła liczenia. Wyjście: data plus lista zastosowanych reguł (art. 112, art. 115, „koniec miesiąca kalendarzowego”).
- Krok 4 — bramka: reguły kierują sprawę do kolejki wyjątków albo do zapisu. Przy zapisie do rejestru umów idzie wynik razem z cytatami i offsetami.
- Log decyzji: jeden wiersz na umowę z pięcioma cytatami, pięcioma wskaźnikami, wersją kalkulatora i wersją modelu. Bez wersji obu nie odtworzysz, dlaczego pół roku temu wyszła inna data.
Zysk z tego podziału nie jest estetyczny. Kalkulatorowi piszesz dwadzieścia testów jednostkowych z datami brzegowymi: 29 lutego, termin kończący się 31 kwietnia, sobota, 1 stycznia, umowa z okresem wypowiedzenia dłuższym niż okres podstawowy. Te testy przechodzą albo nie przechodzą. Ekstrakcji mierzysz czułość na zbiorze umów, których daty znasz z innego źródła. Jeśli model zwraca gotową datę, nie masz ani jednego, ani drugiego — masz jedną liczbę, która miesza dwa rodzaje błędów.
Kolejka wyjątków: co agent oddaje człowiekowi i w jakiej kolejności
Dokumentacja Azure jest w tej sprawie jednoznaczna i dla pól krytycznych stawia poprzeczkę wysoko: najlepiej celować w wynik 80 proc. lub wyższy, a w przypadkach bardziej wrażliwych, takich jak dokumenty finansowe czy medyczne, zalecany jest wynik bliski 100 proc., z dodanym etapem przeglądu przez człowieka dla krytycznych przepływów. Przy umowach ramowych próg sam z siebie nie wystarczy, bo część powodów odesłania sprawy do człowieka nie ma nic wspólnego z pewnością odczytu:
- Brak klauzuli. Agent nie znalazł fragmentu dla wymaganej etykiety. Nie jest to to samo co niska pewność — i nie znaczy, że klauzuli nie ma, bo mogła zostać przeniesiona do aneksu.
- Dwa sprzeczne odczyty. Umowa i aneks mają inny okres wypowiedzenia. Kalkulator nie ma reguły pierwszeństwa i nie powinien jej mieć.
- Warunek zamiast daty. Effective Date opisana zdarzeniem („z dniem uruchomienia środowiska produkcyjnego”). Parser odmawia, bo daty nie ma w dokumencie — ona jeszcze nie zaistniała.
- Nowa reguła liczenia. Brzmienie klauzuli nie pasuje do żadnej z reguł w kalkulatorze. Tu człowiek nie poprawia jednej umowy, tylko dopisuje regułę i test.
- Bliski termin. Wyliczona data wypada w ciągu najbliższych 30 dni. Nie dlatego, że odczyt jest wątpliwy, tylko dlatego, że pomyłka jest nieodwracalna.
Kolejność przeglądu ustawia ostatnie kryterium, nie wskaźnik pewności. Data z pewnością 0,62 i terminem za jedenaście miesięcy może poczekać — jest czas na poprawkę. Data z pewnością 0,97 i terminem za sześć dni nie może, bo jeśli jest zła, umowa odnawia się na rok i nikt tego nie cofnie. Ta sama logika ustawia też priorytet, gdy kolejka wyjątków rośnie szybciej, niż zespół ją przerabia: przy pierwszym uruchomieniu na całym zbiorze wyjątków jest zwykle kilkanaście procent, więc przy 180 umowach to dwadzieścia kilka spraw do ręcznego przejścia. Jeśli nie ma kto ich przejąć, przegląd kolejki wyjątków i dopisanie reguł to zakres, który da się wystawić jako osobne zlecenie z opisanym wejściem i wyjściem — zamiast wstrzymywać wdrożenie do czasu, gdy ktoś w zespole znajdzie dwa wolne tygodnie.
Jedna kategoria umów wypada z tego przepływu w całości. Przy subskrypcjach oprogramowania termin rezygnacji często nie siedzi w podpisanym dokumencie, lecz w regulaminie dostawcy, który może się zmienić bez aneksu — a wtedy to brzmienie regulaminu producenta, nie umowa, rozstrzyga o warunkach odstąpienia i zwrotu. Agent nie ma tam czego odczytać, bo dokumentu w zbiorze nie ma. Te pozycje trzeba wyciągnąć z rejestru osobno i śledzić innym narzędziem.
Rachunek za 180 umów: dwa przebiegi i jedna zmiana modelu
Objętość bierzemy ze zbioru CUAD, który dla 510 umów podaje 9 283 strony, czyli średnio nieco ponad 18 stron na umowę. Przy 180 umowach wychodzi około 3 280 stron. Przeliczenie stron na tokeny jest założeniem do podstawienia, nie pomiarem: poniższy rachunek przyjmuje 1 600 tokenów na stronę polskiej umowy, co przy twoich plikach trzeba policzyć tokenizatorem, bo polskie teksty prawnicze z definicjami w nawiasach wypadają w górę tej skali. Przy tym założeniu jeden przebieg to około 5,24 mln tokenów wejścia i około 0,22 mln tokenów wyjścia (pięć etykiet z cytatami na umowę).
Stawki z cennika Anthropic, podanego w dolarach, dla trzech wariantów tego samego przebiegu:
| Wariant przebiegu | Wejście | Koszt wejścia | Koszt wyjścia | Razem |
|---|---|---|---|---|
| Sonnet 4.6, zapytania pojedyncze ($3 / $15 za mln) | 5,24 mln tok. | 15,72 USD | 3,24 USD | 18,96 USD |
| Sonnet 5.5, nowy tokenizator, zapytania pojedyncze ($2 / $10 za mln) | 6,81 mln tok. | 13,62 USD | 2,81 USD | 16,43 USD |
| Sonnet 5.5 przez Batch API (rabat 50 proc.) | 6,81 mln tok. | 6,81 USD | 1,41 USD | 8,22 USD |
Drugi wiersz wyjaśnia najczęstsze zaskoczenie po miesiącu. Cennik odnotowuje, że modele Claude 4.7 i nowsze używają nowszego tokenizatora, który dla tego samego tekstu produkuje około 30 proc. więcej tokenów. Zbiór umów się nie zmienił, a licznik tokenów podskoczył o blisko jedną trzecią. Kto postawił alert budżetowy na liczbie tokenów, dostanie fałszywy alarm. Kto postawił go na dolarach, zobaczy, że rachunek spadł, bo stawka za milion spadła mocniej.
Druga rzecz, która zwykle nie działa tak, jak się planuje, to pamięć podręczna promptu. Cennik podaje, że trafienie w cache kosztuje 10 proc. standardowej ceny wejścia, więc buforowanie zwraca się po jednym odczycie dla okna pięciominutowego i po dwóch dla godzinnego. Przy tym przepływie buforować da się wyłącznie prefiks: polecenie i schemat etykiet, powiedzmy 3 000 tokenów. To 0,54 mln tokenów na 180 wywołań, czyli oszczędność rzędu jednego dolara na przebiegu — około 6 proc. rachunku. Treść umowy jest resztą wejścia i nigdy nie jest trafieniem w cache, bo każdy dokument czytany jest raz. Buforowanie w tym zadaniu nie jest dźwignią kosztową; dźwignią jest Batch API, bo przegląd rejestru umów nie jest zadaniem czasu rzeczywistego.
Rachunek rośnie natomiast z innego powodu i ten powód jest wbudowany w sposób pracy: schemat etykiet zmienia się po pierwszym przeglądzie wyjątków, a wtedy cały zbiór idzie ponownie. Przy trzech iteracjach schematu w pierwszym miesiącu to trzy przebiegi, nie jeden. W budżecie wpisuje się więc nie koszt przebiegu, a koszt przebiegu razy liczba iteracji schematu — i ta druga liczba jest tym, co trzeba ograniczyć, nie stawka za milion tokenów.
Zanim agent dotknie całego zbioru: kolejność uruchomienia
- Wypisz pola wyjściowe i obok każdego postaw literę: P (przepisane z dokumentu), W (wyliczane), I (interpretacyjne). Każde W wyjmij ze schematu modelu i przenieś do kalkulatora.
- Zbierz 20 umów, których daty wypowiedzenia znasz z innego źródła — z rejestru, z korespondencji, z ręcznego przeglądu. To jest twój zbiór odniesienia i powstaje przed pierwszym uruchomieniem, nie po.
- Napisz kalkulator i jego testy przed podłączeniem modelu. Daty brzegowe: 29 lutego, termin kończący się w miesiącu bez odpowiadającego dnia, sobota, dzień ustawowo wolny, okres wypowiedzenia dłuższy niż okres podstawowy.
- Ustal reguły wejścia do kolejki wyjątków i sortowanie po czasie do terminu, nie po wskaźniku pewności.
- Policz tokenizatorem jeden przebieg na dwudziestu umowach, przemnóż przez dziewięć i przez zakładaną liczbę iteracji schematu. Dopiero ta liczba jest kosztem wdrożenia.
- Zapisz w logu wersję modelu i wersję kalkulatora przy każdym wyniku. Zmiana którejkolwiek z nich zmienia daty w rejestrze.
Decyzja do podjęcia jest jedna i wypada przed pierwszym uruchomieniem na pełnym zbiorze: czy dla każdego pola w schemacie wyjściowym umiesz wskazać, czy agent je odczytał, czy wyliczył. Jeśli nie umiesz, wskaźnik pewności przy wynikach nie jest miarą jakości, tylko ozdobą — i pierwszą rzeczą, którą zauważysz, będzie umowa odnowiona na kolejny rok trzy dni po terminie, którego nikt nie przeliczył.