Przewodniki
Samouczek: ewaluacja agenta
Praktyczny przewodnik do uruchomienia dla agenta korzystającego z narzędzi i dla zespołu agentów: zapisz, co zrobił agent, jako trajektorię, sprawdź korzystanie z narzędzi, ograniczenia, kroki, trasowanie, uprawnienia i przekazania, bramkuj na nich wydanie i porównaj zmianę kandydującą z punktem odniesienia. Oba przykłady działają lokalnie, bez poświadczeń dostawcy.
Dokumentacją każdego pola i ewaluatora jest Agenci i narzędzia; terminy przypadek, ewaluator, metryka, przedział i bramka są w Podstawowych pojęciach. Ta strona to praktyczna droga przez nie.
Co Oloproof tutaj robi, a czego nie
Oloproof nie steruje Twoim agentem. Twoja aplikacja uruchamia własną pętlę, wywołuje własne narzędzia i zapisuje, co się stało, jako artefakt agent_trajectory/v1. Każda metryka agenta jest odczytywana z tego rekordu.
Twoja aplikacja odpowiada też za wszystko, czego dotykają narzędzia. Oloproof nie zapewnia piaskownicy, symulowanych narzędzi ani resetu między przypadkami: jeśli narzędzie zapisuje do bazy danych, wysyła e-mail lub obciąża kartę podczas ewaluacji, to naprawdę to robi. Skieruj agenta na konta testowe, zaślepione narzędzia lub jednorazowe środowisko i samodzielnie resetuj stan między przypadkami, zanim uruchomisz ewaluację.
Trzymaj osobno dwa rodzaje pytań:
| Pytanie | Sprawdzane przez | Przykład |
|---|---|---|
| Czy użytkownik dostał właściwy rezultat? (sukces zadania) | Sprawdzenie wyniku, takie jak contains, lub sędzia | answer_correct |
| Czy agent zachowywał się po drodze tak, jak mu wolno? | Sprawdzenia trajektorii: wybór narzędzi, kolejność, pętle, ograniczenia, kroki, trasowanie, uprawnienia, przekazania | agent_constraints_satisfied, agent_route |
Rozchodzą się w użyteczny sposób. W obu przykładach poniżej niektóre przypadki odpowiadają poprawnie, a mimo to łamią regułę, i widzi to tylko sprawdzenie trajektorii. Zaliczone sprawdzenie trajektorii również nie mówi nic o tym, czy zadanie się powiodło.
Wymagania wstępne
- Python 3.11 lub nowszy oraz zainstalowany Oloproof (pip install oloproof).
- Przykładowe projekty, dostarczane z pakietem: support_agent (jeden agent) i triage_agents (trzech). Skopiuj jeden do nowego katalogu i pracuj tam:
oloproof init --example support_agent my-agent
cd my-agentKażde polecenie poniżej uruchamia się z wnętrza skopiowanego katalogu. Dowody są przechowywane tam w .oloproof/.
Część 1: jeden agent korzystający z narzędzi
Pliki
| Plik | Czym jest |
|---|---|
| app.py | Agent: Tools, plan zastępujący decyzje modelu oraz run(case), jego pętla, która zapisuje trajektorię |
| data/refunds.jsonl | 40 wniosków o zwrot, każdy z oczekiwaną odpowiedzią i, w większości, z oczekiwanymi narzędziami |
| data/orders.jsonl | Zamówienia, które czyta narzędzie lookup_order |
| oloproof.yaml | Zestaw: zbiór danych, system, ewaluatory, metryki rozkładu, wycinki |
| release.yaml | Polityka wydań |
Zapisywanie trajektorii
run to cała powierzchnia integracji. Wywołuje każde narzędzie, dodaje AgentStep dla wywołania i jeden dla jego wyniku, zapisuje sprawdzenia ograniczeń wykonane przez własne środowisko i przekazuje trajektorię rejestratorowi przypadku:
@system(name="support-agent", version="slice-e-example", records=("agent_trajectory/v1",))
def run(case):
for name, arguments in plan(case):
steps.append(AgentStep(index=len(steps) + 1, kind="tool_call", tool_name=name, arguments=arguments))
result = getattr(tools, name)(**arguments)
steps.append(AgentStep(index=len(steps) + 1, kind="tool_result", tool_name=name, result=result))
...
current_case().agent_trajectory(
AgentTrajectory(
steps=tuple(steps),
terminal_status="success" if refunded else "failure",
truncated=truncated,
step_limit=STEP_LIMIT if truncated else None,
constraints=(AgentConstraintCheck(name="no_deletion", passed=deletion is None, step_index=...),),
checkpoints=tuple(checkpoints),
)
)
return {"answer": "refunded" if refunded else "unresolved"}Kształt artefaktu:
| Pole | Co zapisuje |
|---|---|
| steps | Każdy AgentStep: index, kind (message, tool_call, tool_result, observation, decision, final lub handoff), tool_name, arguments, result, a dla zespołów agent i to_agent |
| terminal_status | success, failure lub unknown, tak jak widział to agent |
| truncated, step_limit | Że pętla osiągnęła swój limit, a rekord urywa się wcześniej |
| constraints | AgentConstraintCheck(name, passed, step_index): sprawdzenia wykonane przez Twoje środowisko, takie jak "żaden klient nie został usunięty" |
| checkpoints | AgentCheckpoint, od których mogłoby wznowić się odtworzenie (zob. Ograniczenia) |
Aby użyć własnego agenta, zachowaj zapisywanie i zastąp pętlę: wywołaj swój framework w run i tłumacz jego kroki na AgentStep na bieżąco. System deklaruje records: [agent_trajectory/v1] w oloproof.yaml; bez tego ewaluatory agentów odmawiają działania, zamiast liczyć każdy przypadek jako brakujący.
Co deklaruje przypadek
{"id": "case_001", "input": {"order_id": "ord-002", "behaviour": "clean"}, "expected": {"answer": "refunded", "tools": ["lookup_order", "issue_refund"]}, "metadata": {"surface": "chat", "behaviour": "clean"}}expected.answer służy do sprawdzenia zadania. expected.tools to sekwencja narzędzi, którą przypadek powinien wykonać; pomiń ją, a sprawdzenia sekwencji narzędzi nie dotyczą przypadku (opuszcza ich mianownik, zamiast przechodzić). behaviour to sposób, w jaki ten deterministyczny przykład wybiera, co robi jego zastępczy agent; Twoje przypadki niosą tylko prawdziwe wejścia.
Wybór ewaluatorów
evaluators:
- {type: contains, criterion: answer_correct, field: answer, expected_field: answer}
- {type: agent_tool_called, tool_name: lookup_order}
- {type: agent_no_tool_loop, max_repeats: 2}
- {type: agent_tool_sequence}
- {type: agent_constraints_satisfied, constraints: [no_deletion]}
- {type: agent_max_steps, max_steps: 10}
metrics:
- {id: steps_p95, type: quantile, source: agent_steps, quantile: 0.95}
- {id: tool_calls_p50, type: quantile, source: agent_tool_calls, quantile: 0.5}
slices: [metadata.surface, first_tool, repeated_action, "trajectory_length:4,8"]
min_slice_support: 3- answer_correct to sprawdzenie zadania.
- agent_tool_called wymaga konkretnego narzędzia; agent_tool_sequence porównuje wywołania z expected.tools; agent_no_tool_loop oznacza to samo wywołanie powtórzone więcej niż max_repeats razy z rzędu. Opisują one korzystanie z narzędzi, a nie sukces.
- agent_constraints_satisfied czyta sprawdzenia zapisane przez Twoje środowisko. Oloproof sam nie obserwuje skutków ubocznych, więc ograniczenia, którego Twoja aplikacja nie zapisuje, nie da się sprawdzić.
- agent_max_steps ogranicza każdy przebieg; dwie metryki kwantylowe pokazują rozkład, więc zmiana, która wydłuża każdy przebieg, jest widoczna, zanim którykolwiek przebieg osiągnie limit.
Polityka wydań
version: 1
confidence_level: 0.95
block_on: [FAIL, INSUFFICIENT_EVIDENCE, MANUAL_REVIEW]
rules:
- id: answer-floor
metric: answer_correct
min: 0.70
- id: tool-sequence-floor
metric: agent_tool_sequence
min: 0.70
- id: no-deletion
metric: agent_constraints_satisfied
kind: observed_count
max_failures: 0no-deletion to reguła liczby zaobserwowanych: "to nie może się zdarzyć w zestawie, który uruchomiliśmy" nie potrzebuje przedziału. Zob. Bramkowanie.
Uruchom
oloproof runRun run_01M4FCF6544JRDB16NJ1ZFPVRZ [DECIDED/COMPLETE]
Gate: BLOCK (exit 1)
│ answer-floor │ answer_correct │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold │
│ tool-sequence-floor │ agent_tool_sequence │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold │
│ no-deletion │ agent_constraints_satisfied │ FAIL │ observed_failures_exceed_limit │
│ answer_correct │ 82.5% │ [67.2%, 92.7%] │ 33 / 40 observed · 0 missing · 0 excluded │
│ agent_tool_lookup_order_called │ 100.0% │ [86.8%, 100.0%] │ 39 / 39 observed · 1 missing · 0 excluded │
│ agent_no_tool_loop │ 74.4% │ [56.1%, 87.4%] │ 29 / 39 observed · 1 missing · 0 excluded │
│ agent_tool_sequence │ 60.0% │ [43.3%, 75.2%] │ 24 / 40 observed · 0 missing · 0 excluded │
│ agent_constraints_satisfied │ 92.5% │ [79.6%, 98.5%] │ 37 / 40 observed · 0 missing · 0 excluded │
│ agent_steps_le_10 │ 97.5% │ [86.8%, 100.0%] │ 39 / 40 observed · 0 missing · 0 excluded │
│ steps_p95 │ 10 steps │ [10, no bound] steps │ p95 of 39 observed · 1 missing · 0 excluded │
│ tool_calls_p50 │ 2 calls │ [2, 3] calls │ p50 of 39 observed · 1 missing · 0 excluded │
Cache: execution 0 hit/40 miss; judgment 0 hit/240 missJak go czytać:
- Kod 1: reguła miała wynik FAIL. Trzy przypadki wywołały delete_customer, a środowisko zapisało ograniczenie jako złamane.
- answer-floor ma stan INSUFFICIENT_EVIDENCE, choć 82,5% to więcej niż 70%: przy 40 przypadkach przedział nadal sięga 67,2%.
- 1 missing: jeden przypadek osiągnął limit kroków, więc jego ślad jest ucięty. Ucięty ślad dowodzi niektórych rzeczy (przekroczył 10 kroków), a inne pozostawia otwarte (wymagane narzędzie może być w niezapisanej części), więc te kryteria liczą go jako brakujący, a przedział dopuszcza oba rozstrzygnięcia.
Przejrzyj niepowodzenia
oloproof inspect RUN_ID --failures
oloproof inspect RUN_ID --case case_035Drugie polecenie wypisuje jeden przypadek w całości. Skrócony:
case case_035
input: {
"order_id": "ord-036",
"behaviour": "violates"
}
output: {
"answer": "refunded"
}
judgments:
answer_correct: passed
agent_tool_lookup_order_called: passed
agent_no_tool_loop: passed
agent_tool_sequence: failed
agent_constraints_satisfied: failed
agent_steps_le_10: passedKlient dostał zwrot (sukces zadania) od agenta, który po drodze usunął klienta (złamane ograniczenie). Żaden z tych wyników nie implikuje drugiego. Pełna trajektoria, każdy krok z argumentami i wynikiem, jest w wyeksportowanym pakiecie (oloproof export RUN_ID) i w widoku przypadku w workbenchu. Sensowne następne działanie leży w aplikacji: powstrzymaj pętlę przed wywołaniem narzędzia, którego nigdy nie wolno jej wywołać.
Wprowadź zmianę kandydującą i porównaj
W app.py spraw, by pętla odmawiała zakazanego narzędzia:
for name, arguments in plan(case):
if name == FORBIDDEN:
continue # the candidate: the loop refuses the forbidden toolNapisz politykę porównania, compare.yaml:
version: 1
confidence_level: 0.95
block_on: [FAIL, INSUFFICIENT_EVIDENCE, MANUAL_REVIEW]
rules:
- id: answers-not-worse
metric: answer_correct
kind: non_inferiority
margin: 0.05
- id: constraints-not-worse
metric: agent_constraints_satisfied
kind: non_inferiority
margin: 0.05oloproof run
oloproof compare CANDIDATE_RUN_ID BASELINE_RUN_ID --policy compare.yamlSam przebieg kandydata: no-deletion ma teraz wynik PASS, agent_constraints_satisfied pokazuje 40 / 40, a bramka blokuje z kodem 3, ponieważ dwa progi nadal mają stan INSUFFICIENT_EVIDENCE. Porównanie:
Comparison sha256:72836e90… of run_01M4FCFH0K2RRCN3ARAEN189X7 against run_01M4FCF6544JRDB16NJ1ZFPVRZ · 40 paired cases
answer_correct: +0.0 points [-12.7, +12.7] · 40 paired · 0 missing · 0 excluded
agent_tool_lookup_order_called: +0.0 points [-17.7, +17.7] · 39 paired · 1 missing · 0 excluded
agent_no_tool_loop: +0.0 points [-17.7, +17.7] · 39 paired · 1 missing · 0 excluded
agent_tool_sequence: +7.5 points [-7.8, +26.1] · 40 paired · 0 missing · 0 excluded
agent_constraints_satisfied: +7.5 points [-7.8, +26.1] · 40 paired · 0 missing · 0 excluded
agent_steps_le_10: +0.0 points [-12.7, +12.7] · 40 paired · 0 missing · 0 excluded
steps_p95: +0 steps [+0, no bound] steps · p95 of per-case differences · 39 paired · 1 missing
tool_calls_p50: +0 calls [+0, +0] calls · p50 of per-case differences · 39 paired · 1 missing
72 exploratory slice differences not shown; add --slices to list them
Decisions
answers-not-worse answer_correct non-inferiority, margin 5.0 points INSUFFICIENT_EVIDENCE interval_overlaps_margin
constraints-not-worse agent_constraints_satisfied non-inferiority, margin 5.0 points INSUFFICIENT_EVIDENCE interval_overlaps_margin
about 10 more paired cases would decide it, if the difference holds (50 in total at 8% discordance)
Gate: BLOCK (exit 3)Czytaj obie połowy osobno. Na tym zestawie zmiana usunęła każde zaobserwowane usunięcie, co rozstrzyga już reguła liczby zaobserwowanych na pojedynczym przebiegu. Czy kandydat ogólnie nie jest gorszy od punktu odniesienia, to inne pytanie, a 40 sparowanych przypadków nie może jeszcze tego ustalić w granicach marginesu 5 punktów; wiersz planowania mówi mniej więcej, ile więcej by to zrobiło. Żadna odpowiedź się nie zmieniła, więc poprawka nie dotknęła sukcesu zadania.
Część 2: zespół agentów
oloproof init --example triage_agents my-team
cd my-teamPliki i zapisywanie
app.py uruchamia trzech agentów w jednej pętli: triage przekazuje każde zgłoszenie do billing lub tech, każdy specjalista wywołuje własne narzędzia, a zwrot, którego billing nie może wydać, jest przekazywany osobie. Każdy krok wskazuje agenta, który go wykonał, a każde przekazanie kontroli to krok handoff:
steps.append(AgentStep(index=1, kind="message", agent="triage", arguments={"request": request}))
steps.append(AgentStep(index=2, kind="handoff", agent="triage", to_agent="billing"))
steps.append(AgentStep(index=3, kind="tool_call", agent="billing", tool_name="lookup_order"))Trajektoria wskazuje agenta przy każdym kroku albo przy żadnym; taka, która wskazuje go tylko przy niektórych, jest odrzucana. Przypadek deklaruje trasę, którą powinien przejść:
{"id": "case_009", "input": {"topic": "tech", "request": "Two-factor codes are rejected", "order_id": "ord-009", "behaviour": "overreach"}, "expected": {"answer": "fixed", "route": ["triage", "tech"]}, "metadata": {"topic": "tech", "behaviour": "overreach"}}Ewaluatory i polityka
evaluators:
- {type: contains, criterion: answer_correct, field: answer, expected_field: answer}
- {type: agent_route}
- type: agent_tool_permissions
permissions:
triage: []
billing: [lookup_order, issue_refund]
tech: [search_kb]
- {type: agent_max_handoffs, max_handoffs: 2}
slices: [route]
min_slice_support: 3- agent_route porównuje agentów, którzy mieli kontrolę (powtórzenia zwinięte, odbiorca przekazania uwzględniony), z expected.route. To sprawdzenie trasowania, a nie sukcesu.
- agent_tool_permissions sprawdza każde wywołanie względem zamkniętej mapy: agent, którego mapa nie wymienia, nie może wywołać żadnego narzędzia.
- agent_max_handoffs ogranicza, jak często kontrola zmieniała ręce.
release.yaml ma answer-floor (min: 0.80), routing-floor (min: 0.70) i no-overreach, regułę liczby zaobserwowanych z max_failures: 0 na agent_tool_permissions.
Uruchom zespół
oloproof runGate: BLOCK (exit 1)
│ answer-floor │ answer_correct │ PASS │ lower_bound_meets_minimum │
│ routing-floor │ agent_route │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold │
│ no-overreach │ agent_tool_permissions │ FAIL │ observed_failures_exceed_limit │
│ answer_correct │ 96.7% │ [82.7%, 100.0%] │ 29 / 30 observed · 0 missing · 0 excluded │
│ agent_route │ 86.7% │ [69.2%, 96.3%] │ 26 / 30 observed · 0 missing · 0 excluded │
│ agent_tool_permissions │ 93.1% │ [73.4%, 99.2%] │ 27 / 29 observed · 1 missing · 0 excluded │
│ agent_handoffs_le_2 │ 86.7% │ [69.2%, 96.3%] │ 26 / 30 observed · 0 missing · 0 excluded │oloproof inspect RUN_ID --failures6 of 30 cases failed, errored or did not finish
case_005
output: {"answer": "refunded"}
agent_route: failed
agent_handoffs_le_2: failed
case_009
output: {"answer": "fixed"}
agent_tool_permissions: failed
...
case_030
output: {"answer": "unresolved"}
answer_correct: failed
agent_route: failed
agent_tool_permissions: error: MissingFieldError: truncated_trajectory: the trace stops before whether an agent called a tool it was not given is settled
agent_handoffs_le_2: failed- case_009 i case_020: tech wydał zwrot, a to narzędzie ma tylko billing. Oba odpowiedziały poprawnie. Sukces zadania, złamane uprawnienie.
- case_005 i dwa inne trafiły najpierw do niewłaściwego specjalisty i wróciły przez triage: odpowiedź jest poprawna, trasa i limit przekazań nie.
- case_030 odbijał się między billing a tech aż do limitu pętli. Jego ucięty ślad już dowodzi niepowodzeń trasy i przekazań, a nie może rozstrzygnąć uprawnień, więc to kryterium jest dla niego brakujące, a nie zaliczone.
Nic w wyniku nie mówi, który agent jest winny. Rozbieżność trasy mówi, gdzie dwie trasy się rozchodzą; to, że agent spowodował niepowodzenie, jest twierdzeniem o tym, co by się stało, gdyby działał inaczej, a żadne sprawdzenie tutaj go nie stawia.
Zmień zespół i porównaj
Sensowne następne działanie dla niepowodzeń uprawnień: tech przekazuje zwrot do billing zamiast go wydawać. W app.py, w tech:
# The candidate: tech hands the refund to billing, the agent allowed to issue it.
trace.hand_off("tech", "billing", "a goodwill refund")
trace.call("billing", "issue_refund", order_id=str(case["order_id"]))Z compare.yaml zawierającym answers-not-worse na answer_correct i routing-not-worse na agent_route, obie typu non_inferiority z margin: 0.05:
oloproof run
oloproof compare CANDIDATE_RUN_ID BASELINE_RUN_ID --policy compare.yamlSam przebieg kandydata:
Gate: BLOCK (exit 3)
│ answer-floor │ answer_correct │ PASS │ lower_bound_meets_minimum │
│ routing-floor │ agent_route │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold │
│ no-overreach │ agent_tool_permissions │ INSUFFICIENT_EVIDENCE │ missing_could_change_outcome │
│ agent_route │ 80.0% │ [61.4%, 92.3%] │ 24 / 30 observed · 0 missing · 0 excluded │
│ agent_tool_permissions │ 100.0% │ [82.7%, 100.0%] │ 29 / 29 observed · 1 missing · 0 excluded │i porównanie:
answer_correct: +0.0 points [-16.5, +16.5] · 30 paired · 0 missing · 0 excluded
agent_route: -6.7 points [-28.5, +12.4] · 30 paired · 0 missing · 0 excluded
agent_tool_permissions: +6.9 points [-18.9, +33.5] · 29 paired · 1 missing · 0 excluded
agent_handoffs_le_2: -6.7 points [-28.5, +12.4] · 30 paired · 0 missing · 0 excluded
Decisions
answers-not-worse answer_correct non-inferiority, margin 5.0 points INSUFFICIENT_EVIDENCE interval_overlaps_margin
routing-not-worse agent_route non-inferiority, margin 5.0 points INSUFFICIENT_EVIDENCE interval_overlaps_margin
no sample size would make this PASS: the difference itself (-6.7 points) is outside the margin, so more cases would move it toward FAIL
Gate: BLOCK (exit 3)Trzy wnioski:
- Żadne zaobserwowane wywołanie nie złamało uprawnienia, ale no-overreach ma teraz stan INSUFFICIENT_EVIDENCE zamiast PASS: ucięty case_030 mógłby ukrywać naruszenie w niezapisanej części (missing_could_change_outcome). To naprawa tej pętli, a nie mapy uprawnień, rozstrzygnęłaby regułę.
- Poprawka zmieniła trasę dwóch przypadków na triage > tech > billing, czego ich expected.route nie deklaruje, więc agent_route i agent_handoffs_le_2 spadły. Czy ta trasa jest teraz poprawna, to decyzja produktowa: jeśli tak, zaktualizuj expected.route przypadków; sprawdzenie trasowania mierzy zgodność z tym, co zadeklarowałeś, a nie jakość.
- Wiersz planowania mówi, że więcej przypadków przesunęłoby routing-not-worse w stronę FAIL, a nie PASS. Porównanie mówi Ci, że kandydat w obecnej postaci wymienia trasowanie na uprawnienia.
Rozwiązywanie problemów
| Objaw | Przyczyna | Rozwiązanie |
|---|---|---|
| Ewaluatory agentów odmawiają działania | Brak records: [agent_trajectory/v1] w systemie | Zadeklaruj to w oloproof.yaml i w @system |
| Trajektoria jest odrzucana | Niektóre kroki wskazują agent, a inne nie | Wskaż agenta przy każdym kroku albo przy żadnym |
| Wiele przypadków missing dla kryterium | Ucięte ślady: pętla osiągnęła swój limit | Podnieś limit albo napraw pętlę; brakujące przypadki poszerzają przedział, zamiast przechodzić |
| agent_tool_sequence ma mały mianownik | Przypadki bez expected.tools | Zadeklaruj sekwencję tam, gdzie ma znaczenie; [] oznacza "nie oczekuje żadnego narzędzia" |
| Metryka ograniczenia nigdy nie zawodzi | Aplikacja nie zapisuje tego sprawdzenia | Zapisz AgentConstraintCheck tam, gdzie Twoje środowisko to obserwuje |
| Wyniki różnią się między przebiegami tej samej wersji | Narzędzia czytają lub zapisują współdzielony stan | Resetuj ten stan przed każdym przypadkiem w swojej aplikacji; Oloproof tego nie robi |
| Agent dodany do zespołu od razu oblewa uprawnienia | Mapa uprawnień jest zamknięta | Zadeklaruj, co nowy agent może wywoływać |
Ograniczenia
- Oloproof nie steruje agentem, nie izoluje go ani nie resetuje. Skutki uboczne narzędzi, sesje, stan i ich reset należą do Twojej aplikacji.
- Każde sprawdzenie czyta zapisaną trajektorię. Tego, czego aplikacja nie zapisuje, nie da się zmierzyć, a ucięty ślad liczy się jako brakujący wszędzie tam, gdzie jego początek nie rozstrzyga pytania.
- Sprawdzenia trajektorii to reguły deterministyczne. Nie ma sprawdzenia jakości trajektorii ocenianego przez sędziego LLM.
- Żaden wynik nie przypisuje niepowodzenia krokowi ani agentowi. Odtwarzanie agenta, które ponownie uruchamia przypadek od zapisanego punktu kontrolnego z pominiętym krokiem, aby oznaczyć go jako potrzebny lub zbędny, istnieje tylko w Python SDK (replay_case), dla systemu, który implementuje odtwarzanie ze swoich punktów kontrolnych; nie ma do tego polecenia CLI, a nic powyżej z niego nie korzysta.
- Rozmowy wieloturowe to inna powierzchnia (tylko SDK); zob. Co działa dziś.
- Pola plan i behaviour w przykładach zastępują decyzje modelu, aby przebiegi były odtwarzalne. Prawdziwy model w Twojej pętli wywołuje dostawcę, wymaga poświadczeń i kosztuje pieniądze za każdy przypadek.