Agent pre manažment záverečných prác
Go to file
2026-08-16 16:58:16 +02:00
app oprava opewebui 2026-08-15 01:52:06 +02:00
evaluation upravy runnera 2026-08-16 16:57:46 +02:00
scripts uprava 2026-08-16 16:14:13 +02:00
test pridanie testu 2026-08-16 16:58:16 +02:00
.dockerignore Zlepšenia 2026-07-28 23:56:03 +02:00
.gitignore Hybrid vyhladavanie s embedding 2026-08-12 00:53:26 +02:00
docker-compose.yml upravy 2026-08-13 21:39:42 +02:00
Dockerfile Dockerfile 2026-08-15 00:59:53 +02:00
README.md readme 2026-08-16 01:17:19 +02:00
requirements-dev.txt Zlepšenia 2026-07-28 23:56:03 +02:00
requirements.txt Hybrid vyhladavanie s embedding 2026-08-12 00:53:26 +02:00

ZP Agent

Backend pre indexovanie, hybridné vyhľadávanie a RAG nad repozitárom záverečných prác zpwiki.

Projekt načítava Markdown dokumenty, spracuje YAML metadata, rozdelí obsah na tokenové chunky a vytvorí SQLite index kombinujúci FTS5 fulltextové vyhľadávanie a embeddingy. Nad hybridným vyhľadávaním je vytvorená RAG vrstva, ktorá pripravuje kontext, zdroje a pravidlá pre odpoveď jazykového modelu. API je integrované so školským OpenWebUI ako OpenAPI Tool Server.

Súčasná hlavná retrieval vetva používa klasický hybridný RAG: FTS5/BM25 + embeddingy + RRF. GraphRAG zatiaľ nie je implementovaný; je preň pripravený samostatný evaluačný dataset a bude sa dopĺňať ako ďalšia experimentálna vetva.

Implementované

  • načítanie Markdown súborov a YAML front matter,
  • normalizácia názvov, autorov, tagov, kategórií a published,
  • tokenové chunkovanie pomocou tiktoken,
  • konfigurovateľná maximálna veľkosť chunku, overlap a minimálna veľkosť chunku,
  • zachovanie názvu dokumentu a hierarchie nadpisov v chunku,
  • SQLite databáza a FTS5 fulltextový index,
  • BM25 vyhľadávanie s podporou diakritiky a prefixových výrazov,
  • vyhľadávacie stratégie all_terms, prefix_terms a any_term,
  • embeddingy pre každý chunk pomocou modelu intfloat/multilingual-e5-small,
  • uloženie embeddingov priamo v SQLite,
  • vektorové vyhľadávanie pomocou cosine similarity,
  • hybridné vyhľadávanie FTS5 + embeddings pomocou RRF,
  • nižšia váha pre slabú any_term FTS stratégiu,
  • lexikálne zvýhodnenie presných alebo veľmi silných zhôd,
  • obmedzenie počtu výsledkov z jedného dokumentu pomocou max_per_document,
  • filtrovanie publikovaných dokumentov,
  • generovanie source_url pre dohľadateľnosť výsledkov,
  • RAG vrstva s pripraveným kontextom, zdrojmi a pravidlami pre grounded odpoveď,
  • rozšírenie RAG kontextu o začiatok rovnakej sekcie (section-lead expansion) bez globálneho zvýšenia max_per_document,
  • pravidlá proti používaniu neoverených informácií a zamieňaniu rôznych typov údajov,
  • no-answer správanie pri chýbajúcej alebo nedostatočne podloženej informácii,
  • FastAPI endpointy /health, /rag, /search, /sync a /webhook/gitea,
  • striktná validácia API vstupov,
  • autorizácia vyhľadávania pomocou X-API-Key alebo Bearer tokenu,
  • autorizácia /sync pomocou samostatného API kľúča,
  • CORS konfigurácia pre OpenWebUI,
  • bezpečnostné HTTP hlavičky,
  • integrácia s OpenWebUI cez OpenAPI Tool Server,
  • Gitea webhook s HMAC-SHA256 podpisom, limitom veľkosti payloadu a kontrolou udalosti a repozitára,
  • zámok proti súbežnému reindexovaniu,
  • atomická výmena databázy po úspešnom reindexovaní,
  • persistentná Hugging Face cache v Docker volume,
  • warm-up embeddingového modelu,
  • retrieval evaluácia pre FTS, embeddings a hybridný retrieval,
  • answer-level RAG evaluácia cez OpenWebUI model a RAG tool,
  • oddelené answer-level overrides bez úpravy frozen retrieval benchmarku,
  • príprava rozšírených datasetov pre extended RAG, GraphRAG, robustness a performance experimenty.

Architektúra

zpwiki
  ↓
Markdown + YAML
  ↓
scan_zpwiki.py
  ↓
normalizované dokumenty
  ↓
build_chunks.py
  ↓
tokenové chunky
  ↓
build_sqlite_index.py
  ↓
SQLite
├── dokumenty
├── metadata
├── chunky
├── FTS5
└── embeddingy
  ↓
search_core.py / search_utils.py
  ↓
hybridné vyhľadávanie
├── FTS5 / BM25
├── embeddingové vyhľadávanie
└── RRF fusion + lexical anchor
  ↓
rag_utils.py
├── výber zdrojov
├── section-lead expansion
├── RAG kontext
└── grounding pravidlá
  ↓
FastAPI /rag
  ↓
OpenWebUI / ZP Agent
  ↓
jazykový model
  ↓
odpoveď + source_url

Synchronizačná vetva:

Gitea push
  ↓
POST /webhook/gitea
  ↓
HMAC + repository + event validácia
  ↓
voliteľný git pull --ff-only
  ↓
rebuild_index.py
  ↓
nový SQLite index
  ↓
atomická výmena databázy

Evaluačná vetva:

evaluation/json_files/*.json
  ↓
retrieval evaluator / RAG answer evaluator
  ↓
runner
  ↓
metriky
  ↓
evaluation/results/

evaluation/results/ nie je v nižšie uvedenom stromčeku, pretože obsahuje generované výstupy experimentov.

Štruktúra projektu

Nižšie je funkčná štruktúra projektu. Testovacie súbory, generované výsledky, cache, __pycache__, Git interné súbory a podobné pomocné artefakty sú zámerne vynechané.

zp-agent/
├── app/
│   ├── main.py
│   ├── routes.py
│   └── security.py
│
├── scripts/
│   ├── common.py
│   ├── scan_zpwiki.py
│   ├── build_chunks.py
│   ├── build_sqlite_index.py
│   ├── embedding_utils.py
│   ├── rag_utils.py
│   ├── rebuild_index.py
│   ├── search_db.py
│   ├── search_core.py
│   └── search_utils.py
│
├── evaluation/
│   ├── evaluate_retrieval.py
│   ├── retrieval_runner.py
│   ├── metrics.py
│   ├── evaluate_rag_answers.py
│   ├── rag_runner.py
│   ├── rag_metrics.py
│   └── json_files/
│       ├── questions.json
│       ├── questions_before_ambiguity_cleanup.json
│       ├── questions_before_validation.json
│       ├── rag_answer_overrides.json
│       ├── questions_extended_2000.json
│       ├── graphrag_questions.json
│       ├── robustness_questions.json
│       └── performance_queries.json
│
├── data/
│   ├── documents.json
│   ├── chunks.json
│   └── zp_index.sqlite
│
├── Dockerfile
├── docker-compose.yml
├── requirements.txt
├── requirements-dev.txt
└── README.md

app/

app/main.py

  • vytvára FastAPI aplikáciu,
  • nastavuje lifespan aplikácie,
  • validuje bezpečnostnú konfiguráciu pri štarte,
  • vykonáva warm-up embeddingovej vrstvy,
  • nastavuje CORS a bezpečnostné hlavičky,
  • pripája API routery,
  • ponecháva OpenAPI schému dostupnú pre OpenWebUI.

Interaktívne Swagger/Redoc rozhranie môže byť v produkčnej konfigurácii vypnuté. Pre integráciu OpenWebUI je dôležitý endpoint:

/openapi.json

app/routes.py

  • definuje /health,
  • definuje verejne publikovaný RAG nástroj /rag,
  • obsahuje interné/zabezpečené /search a /sync,
  • obsluhuje /webhook/gitea,
  • vykonáva validáciu requestov a sanitizáciu chýb,
  • používa reindexovací zámok,
  • kontroluje webhook payload pred spracovaním.

app/security.py

  • spracúva SEARCH_API_KEY,
  • spracúva SYNC_API_KEY,
  • spracúva WEBHOOK_SECRET,
  • vyžaduje dostatočne dlhé a navzájom odlišné tajomstvá,
  • používa bezpečné porovnávanie autentifikačných hodnôt,
  • validuje očakávaný Gitea repozitár a súvisiacu konfiguráciu.

scripts/

common.py

Spoločné utility a konfiguračné funkcie používané indexovacou a vyhľadávacou vrstvou.

scan_zpwiki.py

  • prechádza repozitár zpwiki,
  • načítava Markdown a YAML front matter,
  • normalizuje dokumentové metadata,
  • pripravuje dokumenty na ďalšie spracovanie.

build_chunks.py

  • rozdeľuje dokumenty na tokenové chunky,
  • používa tiktoken,
  • zachováva nadpisy, kódové bloky a tabuľky,
  • podporuje tokenový overlap,
  • eviduje token count a hash obsahu chunku.

build_sqlite_index.py

  • vytvára SQLite databázu,
  • ukladá dokumenty, chunky a metadata,
  • vytvára FTS5 index,
  • ukladá embeddingy do SQLite,
  • pripravuje databázu pre hybridný retrieval.

embedding_utils.py

  • načítava embeddingový model,
  • vytvára embeddingy pre dokumenty a query,
  • normalizuje vektory,
  • poskytuje utility pre vektorové vyhľadávanie.

search_core.py

Nízkoúrovňové jadro vyhľadávania:

  • normalizácia query,
  • FTS5 vyhľadávanie,
  • embeddingové vyhľadávanie,
  • scoring,
  • RRF fusion,
  • lexical anchor,
  • metadata,
  • diverzifikácia výsledkov.

search_utils.py

Vyššia orchestration vrstva nad search_core.py a kompatibilné vyhľadávacie utility používané ostatnými časťami projektu.

search_db.py

CLI rozhranie na ručné vyhľadávanie nad lokálnym SQLite indexom.

rag_utils.py

  • zostavuje RAG kontext,
  • pripravuje zdrojové metadata,
  • pridáva source_url,
  • aplikuje grounding pravidlá,
  • podporuje no-answer správanie,
  • rozširuje primárny chunk o začiatok rovnakej sekcie,
  • zachováva väzbu medzi primárnym chunkom a section-lead chunkom.

rebuild_index.py

Orchestruje kompletný rebuild:

scan
→ chunking
→ SQLite/FTS
→ embeddings
→ validácia
→ atomická výmena DB

evaluation/

evaluate_retrieval.py

CLI vstup pre retrieval benchmark. Umožňuje spúšťať DEV, TEST alebo celý dataset a používa strict dataset validáciu.

retrieval_runner.py

Spúšťa jednotlivé retrieval stratégie nad evaluačnými otázkami.

metrics.py

Počíta retrieval metriky, napríklad:

Hit@1
Hit@3
Hit@5
MRR
Recall@5

evaluate_rag_answers.py

CLI vstup pre answer-level RAG evaluáciu. Hodnotí celý tok:

otázka
→ OpenWebUI model
→ ZP Agent tool
→ /rag
→ finálna odpoveď

Podporuje answer-level overrides, aby nebolo potrebné meniť frozen retrieval benchmark pri otázkach, ktoré sú pre generatívnu evaluáciu nejednoznačné.

rag_runner.py

Spúšťa jednotlivé answer-level prípady a komunikuje s OpenWebUI/API.

rag_metrics.py

Počíta answer-level metriky, napríklad:

  • prítomnosť očakávaných faktov,
  • správnosť source_url,
  • should_answer,
  • použitie toolu,
  • strict pass,
  • latency a tokenové údaje.

evaluation/json_files/

questions.json

Hlavný frozen benchmark pre klasický retrieval a RAG. Po zmrazení benchmarku sa nemá meniť len preto, aby sa zlepšil výsledok answer-level evaluácie.

rag_answer_overrides.json

Obsahuje iba answer-level úpravy formulácie alebo očakávaní pri nejednoznačných otázkach. Retrieval benchmark tým ostáva nezmenený.

questions_before_ambiguity_cleanup.json

Historická záloha datasetu pred úpravami nejednoznačností.

questions_before_validation.json

Historická záloha datasetu pred validačnými úpravami.

questions_extended_2000.json

Rozšírený benchmark s presne 2000 otázkami. Je pripravený pre neskoršie rozsiahlejšie experimenty nad klasickým retrievalom a RAG.

Obsahuje kombináciu:

  • faktických otázok,
  • parafráz,
  • otázok bez diakritiky,
  • preklepov,
  • krátkych query,
  • no-answer prípadov,
  • negatívnej verifikácie,
  • multi-document otázok,
  • porovnávania,
  • citation-oriented prípadov.

Tento dataset je zatiaľ pripravený, ale nemá sa používať na priebežné ladenie frozen benchmarku.

graphrag_questions.json

Samostatný benchmark pripravený pre budúcu GraphRAG vetvu.

Obsahuje 500 otázok zameraných na:

  • multi-hop vzťahy,
  • spoločné témy,
  • spoločné roky,
  • person → title → year,
  • person → topic → title,
  • person → category → author,
  • agregácie,
  • konjunktívnu disambiguáciu,
  • multi-document reasoning.

Dataset obsahuje aj GraphRAG metadata ako:

graph.task
graph.hop_count
graph.start_entities
graph.expected_entities
graph.expected_relations
graph.expected_paths

Dôležité: existencia tohto datasetu neznamená, že je GraphRAG už implementovaný. Dataset je pripravený na neskorší vývoj a porovnanie.

robustness_questions.json

Samostatný dataset s 200 otázkami pre testovanie robustnosti.

Pokrýva napríklad:

  • chýbajúcu diakritiku,
  • preklepy,
  • nekonzistentnú kapitalizáciu a interpunkciu,
  • nerelevantný šum,
  • prompt injection,
  • konfliktné tvrdenia používateľa,
  • tlak na halucinovanie,
  • no-answer grounding,
  • ambiguity/disambiguation,
  • integritu citácií,
  • kombinovaný vstupný šum.

Každá položka obsahuje aj robustness metadata s typom útoku, perturbáciou, očakávaným správaním a závažnosťou.

performance_queries.json

Samostatný workload s 200 query pre budúce performance a stress experimenty.

Profily zahŕňajú:

  • baseline single-document query,
  • krátke query,
  • noisy query,
  • multi-document query,
  • no-answer query,
  • query s väčším retrieval limitom,
  • context-heavy query,
  • opakované hot query.

Súbor samotný performance nemeria. Je to vstup pre budúci samostatný performance runner, ktorý bude volať /rag a merať napríklad:

mean latency
median
P50
P95
P99
requests/second
error rate
timeout rate
cold vs warm latency

Stress režim bude nad rovnakým workloadom zvyšovať paralelizmus a sledovať správanie systému pri rastúcej záťaži.

Konfigurácia

V koreňovom priečinku vytvor .env:

WEBHOOK_SECRET=<náhodná hodnota s minimálne 32 znakmi>
SYNC_API_KEY=<iná náhodná hodnota s minimálne 32 znakmi>
SEARCH_API_KEY=<ďalšia náhodná hodnota s minimálne 32 znakmi>
EXPECTED_GITEA_REPOSITORY=KEMT/zpwiki
WEBHOOK_PULL_GIT=false

# Voliteľné
EMBEDDING_MODEL=intfloat/multilingual-e5-small
EMBEDDING_BATCH_SIZE=32

Tajomstvá je možné vygenerovať príkazom:

openssl rand -hex 32

Súbor .env sa nesmie commitovať.

Chunkovanie je možné konfigurovať pomocou premenných prostredia:

CHUNK_MAX_TOKENS=450
CHUNK_OVERLAP_TOKENS=70
CHUNK_MIN_TOKENS=80
CHUNK_TOKEN_ENCODING=cl100k_base

Spustenie cez Docker

docker compose up -d --build

Kontrola služby:

curl http://127.0.0.1:8000/health

OpenAPI schéma:

http://127.0.0.1:8000/openapi.json

Logy:

docker compose logs -f zp-agent-api

Zastavenie:

docker compose down

Hugging Face cache je uložená v persistentnom Docker volume, takže sa embeddingový model pri bežnom reštarte kontajnera nemusí znova sťahovať.

Reindexovanie

Celý proces načíta dokumenty, vytvorí chunky, obnoví FTS5 index a vytvorí embedding pre každý chunk:

docker compose run --rm zp-agent-api python scripts/rebuild_index.py

Vzniknú súbory:

data/documents.json
data/chunks.json
data/zp_index.sqlite

Databáza obsahuje dokumenty, chunky, FTS5 index, metadata a embeddingy.

Pri automatickom reindexovaní sa používa zámok proti súbežnému spusteniu a atomická výmena databázy po úspešnom vytvorení nového indexu.

Hybridné vyhľadávanie

Vyhľadávanie kombinuje:

dotaz
├── FTS5 / BM25
└── embeddingové vyhľadávanie
        ↓
   RRF fusion
        ↓
   lexical anchor
        ↓
   výsledky

FTS5 používa stratégie:

all_terms
prefix_terms
any_term

Presné lexikálne výsledky majú prednosť pred slabšími sémantickými zhodami. Pri slabšej any_term stratégii sa znižuje jej váha a väčší význam môže dostať embeddingové vyhľadávanie.

Test z terminálu:

docker compose run --rm zp-agent-api \
  python scripts/search_db.py "rag agent" --limit 5

Pred volaním API načítaj premenné z .env:

set -a
source .env
set +a

Vyhľadávanie cez zabezpečené API:

curl -X POST http://127.0.0.1:8000/search \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $SEARCH_API_KEY" \
  -d '{
    "query": "strojový preklad",
    "limit": 3,
    "published_only": false,
    "max_per_document": 1
  }'

API používa hybridný engine:

hybrid_fts5_embeddings

max_per_document=1 zabezpečí, že sa pri požiadavke na viac výsledkov preferujú rôzne dokumenty namiesto viacerých chunkov z rovnakého dokumentu.

RAG

Nad hybridným retrievalom je implementovaná RAG vrstva v scripts/rag_utils.py.

Endpoint /rag vyhľadá relevantné dokumenty a pripraví:

  • textový kontext pre jazykový model,
  • metadata použitých zdrojov,
  • názov a autora dokumentu,
  • source_url,
  • interné retrieval informácie,
  • pravidlá pre grounded odpoveď.

RAG pravidlá požadujú, aby model odpovedal iba podľa poskytnutých zdrojov. Zároveň rozlišujú údaje, ktoré sa môžu ľahko zameniť, napríklad autora dokumentu, osobu, o ktorej dokument pojednáva, rok začiatku štúdia a rok záverečnej práce.

Ak sa relevantná informácia nenachádza priamo v primárnom chunke, RAG vrstva môže k rovnakému zdroju doplniť začiatok rovnakej sekcie. Táto section-lead expanzia umožňuje zachovať retrieval max_per_document=1, ale zároveň doplniť názov témy, rok alebo inú informáciu umiestnenú na začiatku sekcie.

Pri nedostatočnej podpore má model odmietnuť informáciu domýšľať.

Príklad:

curl -X POST http://127.0.0.1:8000/rag \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $SEARCH_API_KEY" \
  -d '{
    "query": "V akom roku robil Ján Holp diplomovú prácu?",
    "limit": 5,
    "published_only": false,
    "max_per_document": 1
  }'

OpenWebUI

ZP Agent je pripojený do OpenWebUI ako OpenAPI Tool Server.

OpenWebUI používa OpenAPI schému ZP Agent API a Bearer autentifikáciu pre vyhľadávací/RAG nástroj.

Tok požiadavky:

používateľ
  ↓
OpenWebUI
  ↓
jazykový model
  ↓
ZP Agent /rag
  ↓
hybrid retrieval
  ↓
RAG kontext + zdroje
  ↓
jazykový model
  ↓
odpoveď

Výsledná odpoveď má byť grounded v ZP Wiki a má používať relevantný source_url.

Retrieval evaluácia

Frozen retrieval benchmark sa spúšťa napríklad:

python evaluation/evaluate_retrieval.py \
  --split dev \
  --strict-dataset

Podporované režimy:

dev
test
all

Vyhodnocujú sa samostatne:

FTS
vector
hybrid

a metriky:

Hit@1
Hit@3
Hit@5
MRR
Recall@5

TEST split sa nemá používať na priebežné ladenie retrieval konfigurácie.

RAG answer evaluácia

Answer-level evaluácia používa:

python evaluation/evaluate_rag_answers.py --split dev

Evaluuje kompletný model/tool/RAG tok a od retrieval benchmarku je oddelená.

Ak je pôvodná otázka vhodná pre retrieval, ale nejednoznačná pre generatívnu odpoveď, jej answer-level formulácia sa upraví iba cez:

evaluation/json_files/rag_answer_overrides.json

Pôvodný frozen questions.json tým ostáva nezmenený.

Manuálna synchronizácia

Manuálne reindexovanie cez zabezpečený endpoint:

curl -X POST http://127.0.0.1:8000/sync \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $SYNC_API_KEY" \
  -d '{"pull_git": false}'

Gitea webhook

Endpoint:

POST /webhook/gitea

Webhook overuje:

  • HMAC-SHA256 podpis,
  • typ Gitea udalosti,
  • očakávaný repozitár,
  • maximálnu veľkosť payloadu,
  • stav reindexovacieho zámku.

Očakávaný repozitár:

EXPECTED_GITEA_REPOSITORY=KEMT/zpwiki

Ak je povolené:

WEBHOOK_PULL_GIT=true

pred reindexovaním sa vykoná:

git pull --ff-only

Bezpečnosť

Vyhľadávanie podporuje API key:

X-API-Key: <SEARCH_API_KEY>

aj Bearer autentifikáciu:

Authorization: Bearer <SEARCH_API_KEY>

Endpoint /sync používa samostatný SYNC_API_KEY a webhook samostatný WEBHOOK_SECRET.

Tajomstvá sa ukladajú do .env, ktorý nesmie byť súčasťou Git repozitára.

Bezpečnostná vrstva zároveň kontroluje minimálnu dĺžku tajomstiev, odlišnosť jednotlivých secretov a používa bezpečné porovnávanie hodnôt.

Testy

Inštalácia testovacích závislostí:

pip install -r requirements-dev.txt

Bežné automatizované testy:

pytest -q

Kontrola syntaxe najdôležitejších upravovaných modulov:

python -m py_compile \
  scripts/rag_utils.py \
  evaluation/evaluate_rag_answers.py \
  evaluation/rag_runner.py \
  evaluation/rag_metrics.py

Pred checkpointom je vhodné použiť aj:

git diff --check
git status

Pevný počet pytest výsledkov nie je v README uvádzaný, pretože sa s vývojom mení. Aktuálny stav sa má vždy potvrdiť novým spustením testov na konkrétnom commite.

Pripravené, ale zatiaľ neaktívne experimenty

Nasledujúce datasety sú pripravené, ale nemajú sa teraz používať na priebežné ladenie aktuálneho frozen benchmarku:

questions_extended_2000.json
graphrag_questions.json
robustness_questions.json
performance_queries.json

Odporúčané poradie ich neskoršieho použitia:

stabilný klasický RAG
  ↓
extended benchmark
  ↓
robustness benchmark
  ↓
GraphRAG implementácia
  ↓
GraphRAG benchmark
  ↓
performance benchmark
  ↓
stress test
  ↓
finálne experimenty

Najbližší postup

Najbližšia vývojová etapa je zámerne menšia a má uzavrieť existujúci klasický RAG pred otvorením ďalších experimentov.

1. Uzavretie retrieval/regresie

Najprv sa má potvrdiť, že aktuálne zmeny neovplyvnili frozen retrieval baseline.

Postup:

py_compile
↓
pytest
↓
frozen retrieval DEV strict
↓
porovnanie s uloženým baseline
↓
git diff --check
↓
retrieval lock

Do retrieval scoringu sa potom nemá zasahovať bez nového experimentálneho dôvodu.

2. Regresia section-lead RAG kontextu

Treba potvrdiť, že section-lead expanzia:

  • opravuje prípady, kde primárny chunk chýba o názov/tému/rok,
  • nepridáva duplicitný chunk,
  • zostáva v rovnakom dokumente a sekcii,
  • nemení retrieval max_per_document=1,
  • nevytvára zbytočne veľký kontext.

3. retry + backoff + resume pre answer evaluator

Pred spustením veľkého DEV answer benchmarku sa má evaluator doplniť tak, aby dlhý beh nebol znehodnotený jedným timeoutom alebo dočasnou chybou API.

Plánované správanie:

request
  ↓
úspech ───────────────→ uložiť výsledok
  │
  └─ timeout / 429 / 5xx
           ↓
       retry
           ↓
 exponential backoff
           ↓
       retry limit

Resume mechanizmus má:

  • priebežne ukladať .partial.json,
  • pri novom spustení načítať existujúci partial výsledok,
  • overiť kompatibilitu modelu/datasetu/splitu,
  • preskočiť už úspešne dokončené otázky,
  • pokračovať od ďalšej otázky,
  • neprepisovať hotové výsledky bez explicitnej voľby,
  • po úspešnom dokončení vytvoriť finálny JSON/CSV výstup.

Zároveň je vhodné:

  • rozlišovať retryable a permanentné chyby,
  • logovať číslo pokusu a dôvod retry,
  • mať konfigurovateľný maximálny počet pokusov,
  • mať konfigurovateľný počiatočný backoff,
  • používať mierny delay medzi otázkami,
  • validovať typy answer-level datasetových polí,
  • nenačítavať osobný OpenWebUI API kľúč z fallback súboru, ak má byť podľa bezpečnostnej politiky dostupný iba cez environment.