Skip to content

Przewodniki

Postęp i współbieżność

Zestaw uruchamiany na działającym modelu trwa minuty, a większość z nich schodzi na czekaniu na model. Ta strona opisuje, ile wywołań Oloproof utrzymuje jednocześnie w toku, co pokazuje podczas ich wykonywania i jak sprawdzić, ile dodatkowych przypadków rozstrzygnęłoby regułę, która nie dała rozstrzygnięcia.

Współbieżność

concurrency: w oloproof.yaml ogranicza liczbę wywołań w toku jednocześnie:

concurrency:
  system: 4
  judge: 4

system ogranicza wywołania testowanego systemu i domyślnie wynosi 8. judge ogranicza wywołania sędziów LLM i domyślnie wynosi 4. Są rozdzielone, ponieważ oba zwykle podlegają różnym limitom częstotliwości.

Sto dwadzieścia przypadków wobec systemu, któremu jedno wywołanie zajmuje jedną dziesiątą sekundy:

system:Czas rzeczywisty
113,4 s
161,7 s
bez zmian, ponowne uruchomienie0,4 s

Ostatni wiersz to pamięć podręczna, a nie współbieżność: każde wykonanie zostało użyte ponownie. Współbieżność nie należy do tożsamości systemu, więc jej zmiana nigdy nie unieważnia tego, co zapisano.

Każdy przypadek to osobne wywołanie. Oloproof nie grupuje przypadków w API wsadowe dostawcy, więc rabat dostawcy za przetwarzanie wsadowe nie jest przez nie dostępny; przebieg przyspieszają współbieżność i pamięć podręczna.

Ponowienia

Dostawca sędziego lub system HTTP, który odpowiada 429 lub 5xx, przekracza limit czasu albo zrywa połączenie, jest ponawiany z odczekaniem, maksymalnie cztery próby, i nigdy wcześniej, niż żąda nagłówek Retry-After. System wywoływalny włącza to, zgłaszając TransientError z oloproof z retryable=True:

from oloproof import TransientError, system


@system(name="example-support-bot", version="1")
def answer(case):
    ...
    raise TransientError("provider timed out", retryable=True)

retryable domyślnie ma wartość False. Bez tego błąd jest rejestrowany przy przypadku, który jest wtedy brakujący, a nie ponawiany. System, który w ten sposób zgłosił wyjątek przy pierwszym wywołaniu dla każdego z trzydziestu przypadków i odpowiedział przy drugim:

│ exact_label │ 100.0%   │ [88.4%, 100.0%] │ 30 / 30 observed · 0 missing · 0 excluded │

Ten sam system po usunięciu retryable=True:

│ exact_label │          │ [0.0%, 100.0%] │ 0 / 0 observed · 30 missing · 0 excluded │

Co pokazuje przebieg w trakcie działania

W terminalu oloproof run odświeża widok na żywo na standardowym wyjściu błędów: ukończone przypadki, trafienia w pamięci podręcznej, błędy i tymczasową estymatę dla każdej metryki binarnej. Jedna klatka:

                    56/120 cases · 0 cached · 0 errors
┏━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Metric      ┃ Estimate ┃ Provisional interval ┃ Cases                   ┃
┡━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ exact_label │ 89.8%    │ [78.2%, 95.6%]       │ 49 observed · 0 missing │
└─────────────┴──────────┴──────────────────────┴─────────────────────────┘
     Provisional Wilson estimates over finished cases; not a decision.

Podpis jest regułą. Przedział tymczasowy to przedział Wilsona nad tym, co się zakończyło — warto go obserwować, ale nie należy na jego podstawie podejmować decyzji: jest przeliczany w miarę napływu przypadków, a przedział sprawdzany wielokrotnie, aż wygląda dobrze, nie jest już przedziałem 95%. Nic na jego podstawie nie zatrzymuje przebiegu wcześniej. Decyzja zapada raz, na podstawie kompletnych dowodów, metodą wskazaną w polityce.

Poza terminalem, na przykład w CI, widok na żywo nie jest rysowany, a tabele są drukowane raz, na końcu.

Strumień zdarzeń

--json zapisuje ten sam postęp jako jeden obiekt JSON na wiersz na standardowym wyjściu, a tabele na standardowym wyjściu błędów:

oloproof run --json

Przebieg 120 przypadków, zapisany do run.ndjson i zliczony za pomocą jq -r '.type' run.ndjson | sort | uniq -c, emituje:

 120 case_executed
 120 case_judged
  11 provisional_metrics
   1 run_finished
   2 run_phase_changed
   1 run_started

Każde zdarzenie niesie identyfikator przebiegu i znacznik czasu:

{"run_id":"run_01M3C3ZNXPVQJCDF31DJSBXBHC","timestamp":"2026-09-25T11:07:37.782628Z","type":"run_started","suite_digest":"sha256:c6ae32f25d38ddac175f688c15c40991c1e0ec5348f32bfabd9c493a3f688c28","cases":120}
{"run_id":"run_01M3C3ZNXPVQJCDF31DJSBXBHC","timestamp":"2026-09-25T11:07:37.885640Z","type":"case_executed","scenario_id":"q000","status":"OK","from_cache":false,"latency_ms":102.11420899941004}
{"run_id":"run_01M3C3ZNXPVQJCDF31DJSBXBHC","timestamp":"2026-09-25T11:07:37.885667Z","type":"case_judged","scenario_id":"q000","criterion":"exact_label","status":"OK","passed":true,"score":null,"from_cache":false}
{"run_id":"run_01M3C3ZNXPVQJCDF31DJSBXBHC","timestamp":"2026-09-25T11:07:41.362779Z","type":"run_finished","status":"DECIDED","completeness":"COMPLETE","exit_code":0}

provisional_metrics niesie bieżący przedział Wilsona dla każdej metryki binarnej:

jq -c 'select(.type == "provisional_metrics") | [.cases_done, .metrics[0].estimate, .metrics[0].wilson_lower, .metrics[0].wilson_upper]' run.ndjson
[1,1.0,0.20654931411298355,1.0]
[13,0.8461538461538461,0.5776536895684791,0.9567418216820717]
[25,0.88,0.7004420606159933,0.9583318285288502]
[37,0.8918918918918919,0.7529146844205937,0.9571481006263428]

Nie należy zamykać potoku przedwcześnie. Czytnik, który kończy po kilku pierwszych wierszach, taki jak head, kończy przebieg, zanim ten zapisze ostatnie przypadki, a przebieg zostaje zarejestrowany jako RUN_ERROR/PARTIAL.

Ile więcej by to rozstrzygnęło

Reguła z wynikiem INSUFFICIENT_EVIDENCE nie zawiodła; zestaw był zbyt mały, by oddzielić wynik od progu. oloproof plan podaje, o ile musiałby być większy, wyceniając to na podstawie tego, co przebieg już zużył. Dla osiemnastoprzypadkowego examples/support_bot/:

oloproof plan RUN_ID --run
Run run_01M3C3WS0SBTFAG55M7ECM1EZ4
  observed  18 cases

exact-label-floor: about 1614 more cases would decide it, if the observed rate holds (1632 in total)
  time      <1s – 27s
  tokens    none reported by this run's providers
  assuming  the cases to come resemble the 18 already run
            cases run one after another; concurrency divides the time and not the cost

Wyznaczanie wielkości dla reguły przebiegu jest dopuszczone tylko dla odsetków zaliczeń. Dla średniej plan mówi to wprost, zamiast zgadywać:

Run run_01M3C3W5YWJY65X9YM6N02F3W4: no sample size can be computed for a rule that did not decide.
  error-budget: sizing a run rule is admitted for binary rates only, and days_error is a MEAN metric: a run stores its summary, not the per-case values sizing one would need

Po podaniu zamiast tego identyfikatora porównania planuje reguły porównania i nie wymaga żadnej flagi.

Co dalej

których wyceniane są te szacunki.