diff --git a/README.md b/README.md index 8c2144e..07c2f7b 100644 --- a/README.md +++ b/README.md @@ -3,1541 +3,48 @@ 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. - -Stabilná baseline retrieval vetva používa klasický hybridný RAG: -FTS5/BM25 + embeddingy + RRF. Nad týmto baseline sa vo vetve GraphRAG -dopĺňa knowledge graph uložený v Neo4j. Aktuálne je implementovaná -grafová infraštruktúra, deterministický builder, vizualizácia grafu a -samostatné grafové vyhľadávanie. Grafová vrstva má zdrojovo overený benchmark a zmrazenú opravenú -verziu v7 s novým TESTom 80 kombinácií a regresiou 320 historických otázok, kontrolou všetkých vrátených -typovaných faktov a samostatným overením generovania odpovedí cez OpenWebUI API. Ďalším krokom je natívne zapojenie grafového -nástroja a hlavného agenta do OpenWebUI. - -## 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ď, -- autorizovaný `/answer` s kontrolou faktických väzieb, citácií a úplnosti, - najviac jednou opravou a zostavením finálneho textu z overených údajov; - [OpenWebUI Pipe](tools/answers/openwebui_pipe.py), postup je nižšie v časti OpenWebUI, -- 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, -- Neo4j databáza spúšťaná ako samostatná Docker služba, -- deterministická tvorba knowledge graphu z `documents.json` a - `chunks.json`, -- grafové entity `Person`, `Document`, `DocumentAuthor`, `Thesis`, - `Work`, `Keyword`, `Topic` a `Category`, -- grafové vzťahy pre dokumenty, práce, témy, kategórie a autorstvo, -- uniqueness constraints a opakovateľný rebuild GraphRAG grafu, -- Neo4j Browser na vizualizáciu a kontrolu vytvoreného grafu, -- samostatné grafové vyhľadávanie nad Neo4j s rozpoznaním entít, vzťahov, prác, tém a rokov, -- 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 - -```text -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 -``` - -GraphRAG vývojová vetva: - -```text -documents.json + chunks.json - ↓ -graphrag.py - ↓ -build_graphrag.py - ↓ -Neo4j -├── Person -├── Document -├── Thesis -├── Work -├── Keyword -├── Topic -├── Category -└── DocumentAuthor - ↓ -grafové vzťahy + vizualizácia - ↓ -graph_search.py - ↓ -grafové entity + cesty + zdrojové dokumenty - ↓ -spojenie s klasickým RAG -``` - -V aktuálnom stave je implementované vytvorenie a uloženie knowledge -graphu aj samostatné grafové vyhľadávanie. Jeho zapojenie do `/rag` a -OpenWebUI sa ešte dopĺňa. - -Synchronizačná vetva: - -```text -Gitea push - ↓ -POST /webhook/gitea - ↓ -HMAC + repository + event validácia - ↓ -durable synchronizačná fronta - ↓ -overenie vetvy + git fetch + merge --ff-only - ↓ -nové JSON, SQLite a grafový payload v stagingu - ↓ -koordinované prepnutie SQLite a Neo4j + spoločná verzia dát -``` - -Evaluačná vetva: - -```text -tools/rag/evaluation/json_files/*.json - ↓ -retrieval evaluator / RAG answer evaluator - ↓ -runner - ↓ -metriky - ↓ -tools/rag/evaluation/results/ -``` - -`tools/rag/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é. - -```text -zp-agent/ -├── app/ -│ ├── main.py -│ ├── routes.py -│ └── security.py -│ -├── tools/ -│ ├── answers/ -│ │ ├── answer_delivery.py -│ │ └── openwebui_pipe.py -│ ├── answer_evaluation/ -│ │ ├── checked_generation.py -│ │ ├── context_policy.py -│ │ └── evaluate_graph_answers.py -│ ├── retrieval/ -│ │ ├── publication.py -│ │ ├── retrieval_contract.py -│ │ └── text_budget.py -│ ├── runtime/ -│ │ ├── runtime_assets.py -│ │ ├── runtime_health.py -│ │ ├── tool_health.py -│ │ └── bootstrap_indexes.py -│ ├── sync/ -│ │ ├── index_state.py -│ │ ├── sync_indexes.py -│ │ ├── sync_jobs.py -│ │ └── wiki_git.py -│ ├── rag/ -│ │ ├── common.py -│ │ ├── scan_zpwiki.py -│ │ ├── build_chunks.py -│ │ ├── build_sqlite_index.py -│ │ ├── embedding_utils.py -│ │ ├── rebuild_index.py -│ │ ├── search_core.py -│ │ ├── search_utils.py -│ │ ├── search_db.py -│ │ ├── rag_utils.py -│ │ ├── rag_document_expansion.py -│ │ ├── rag_query_evidence.py -│ │ ├── rag_supplemental_expansion.py -│ │ ├── run_e5_regression.sh -│ │ ├── run_e5_1_regression.sh -│ │ ├── evaluation/ -│ │ │ ├── evaluate_retrieval.py -│ │ │ ├── evaluate_rag_answers.py -│ │ │ ├── retrieval_runner.py -│ │ │ ├── rag_runner.py -│ │ │ ├── metrics.py -│ │ │ ├── rag_metrics.py -│ │ │ └── json_files/ -│ │ └── tests/ -│ │ -│ └── graphrag/ -│ ├── graph_db.py -│ ├── graphrag.py -│ ├── build_graphrag.py -│ ├── graph_search.py -│ ├── neo4j_smoke.py -│ ├── evaluation/ -│ │ └── graphrag_questions.json -│ └── tests/ -│ -├── test/ -│ ├── test_api.py -│ ├── test_configuration.py -│ └── test_security.py -│ -├── packages/ -│ └── openwebui/ -│ ├── rag/tool.py -│ └── graphrag/tool.py -│ -├── scripts/ -│ ├── start_project.sh -│ ├── compose.sh -│ ├── build_tool_packages.py -│ └── verify_project.py -│ -├── data/ -│ ├── documents.json -│ ├── chunks.json -│ └── zp_index.sqlite -│ -├── deployment/ -│ ├── Dockerfile -│ ├── docker-compose.yml -│ ├── requirements.txt -│ └── requirements-dev.txt -└── README.md -``` - -`answers/` doručuje overené odpovede a obsahuje inštalovateľný OpenWebUI Pipe. -`answer_evaluation/` obsahuje kontrolu odpovedí, renderer a evaluačné klienty. -`retrieval/` zdieľa dátový kontrakt, publikačnú politiku a delenie podľa rozpočtu. -`runtime/` pripravuje model/tokenizér a kontroluje štart a dostupnosť služieb. -`sync/` spravuje Git, frontu a spoločné publikovanie SQLite/Neo4j indexov. -`packages/openwebui/` obsahuje samostatne inštalovateľné Tools. Každý -`tool.py` potrebuje iba štandardnú knižnicu a Pydantic dostupný v OpenWebUI; -neimportuje backend ani druhý balík. Je to klient existujúceho API. -V koreňovom `tools/` zostáva iba `__init__.py`. - -Na Gite je z dokumentácie iba tento hlavný README. Vedľajšie návody, -pracovné záznamy a textové správy ostávajú lokálne a sú ignorované. -JSON/CSV výsledky a pôvodné experimentálne manifesty zostávajú zachované. -Historické zmrazené merania sa reprodukujú v ich pôvodnom Git checkoute; -presun modulov nemení ich uložené odtlačky ani výsledky. - -### `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: - -```text -/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. - -### `tools/rag/` - -`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. - -### `tools/graphrag/` - -`graph_db.py` - -- načítava konfiguráciu Neo4j, -- vytvára Neo4j driver, -- poskytuje kontrolu spojenia s grafovou databázou. - -`graphrag.py` - -- pripravuje dátový model knowledge graphu, -- normalizuje grafové identifikátory, -- extrahuje osoby, práce, roky, témy, kategórie a súvisiace metadata, -- pripravuje uzly a vzťahy pre zápis do Neo4j. - -`build_graphrag.py` - -- načíta `documents.json` a `chunks.json`, -- vytvorí GraphRAG payload, -- vytvorí Neo4j uniqueness constraints, -- zapíše uzly a vzťahy, -- podporuje opakovateľný rebuild spravovanej časti grafu, -- vypíše základné počty uzlov, vzťahov a kvalitu extrakcie názvov prác. - -`graph_search.py` - -- rozpoznáva relevantné osoby a obmedzenia v otázke, -- vyhľadáva práce, témy, roky a spoločné vzťahy v Neo4j, -- vracia grafové cesty, fakty a zdrojové dokumenty, -- slúži ako základ budúceho GraphRAG nástroja pre OpenWebUI. - -`neo4j_smoke.py` - -Jednoduchý smoke test pripojenia k Neo4j používaný pri kontrole Docker -prostredia. - -`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: - -```text -scan -→ chunking -→ SQLite/FTS -→ embeddings -→ validácia -→ atomická výmena DB -``` - -### `tools/rag/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: - -```text -Hit@1 -Hit@3 -Hit@5 -MRR -Recall@5 -``` - -`evaluate_rag_answers.py` - -CLI vstup pre answer-level RAG evaluáciu. Hodnotí celý tok: - -```text -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. - -### `tools/rag/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.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 benchmark je po oddelení nástrojov uložený samostatne v: - -```text -tools/graphrag/evaluation/graphrag_questions.json -``` - -Obsahuje 500 otázok zameraných na grafové a viacvzťahové dopyty. - -`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: - -```text -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`: - -```dotenv -WEBHOOK_SECRET= -SYNC_API_KEY= -SEARCH_API_KEY=<ďalšia náhodná hodnota s minimálne 32 znakmi> -EXPECTED_GITEA_REPOSITORY=jp170na/zpwiki -EXPECTED_GITEA_BRANCH=master -WEBHOOK_PULL_GIT=true -ZPWIKI_SSH_KEY=/absolutna/cesta/k/ssh_klucu -ZPWIKI_KNOWN_HOSTS=/absolutna/cesta/k/known_hosts - -# Voliteľné -EMBEDDING_MODEL=intfloat/multilingual-e5-small -EMBEDDING_BATCH_SIZE=32 -OPENWEBUI_API_KEY= -ANSWER_MODEL=model120-fast -ANSWER_LLM_URL=https://ui.tukekemt.xyz/api/chat/completions - -# GraphRAG / Neo4j -NEO4J_URI=bolt://localhost:7687 -NEO4J_USER=neo4j -NEO4J_PASSWORD= -NEO4J_DATABASE=neo4j -``` - -Tajomstvá je možné vygenerovať príkazom: - -```bash -openssl rand -hex 32 -``` - -Súbor `.env` sa nesmie commitovať. - -Chunkovanie je možné konfigurovať pomocou premenných prostredia: - -```dotenv -CHUNK_MAX_TOKENS=450 -CHUNK_OVERLAP_TOKENS=70 -CHUNK_MIN_TOKENS=80 -CHUNK_TOKEN_ENCODING=cl100k_base -``` - -## Spustenie cez Docker - -Potrebný je dostupný Docker Engine, natívny Linux Compose v2 a Buildx. -Vo WSL používaj kontext, ku ktorému sa Linux klient vie pripojiť; Windows -kontext s `npipe` tu nie je náhradou Linux socketu. Overenie: - -```bash -docker --context default info -docker compose version -docker buildx version -``` - -Po vytvorení `.env`, klonu `../zpwiki` a SSH konfigurácie spusti: - -```bash -./scripts/start_project.sh -``` - -Dockerfile, Compose a oba zoznamy závislostí sú v `deployment/`. -`.env`, `.gitignore` a `.dockerignore` zostávajú v koreni projektu. -Príkazy Compose spúšťaj cez `./scripts/compose.sh`, napríklad -`./scripts/compose.sh ps`. Obal nastavuje absolútne cesty, koreň build -kontextu a pôvodný názov projektu `zp-agent`, takže sa nemenia dátové volume. -Funguje aj pri spustení cez absolútnu cestu z iného pracovného priečinka. - -Skript štandardne používa kontext `default`, nemení globálny Docker kontext -a spravuje iba projekt `zp-agent`. Iný cieľ nastav cez `ZP_DOCKER_CONTEXT`. -Zostaví image, počká na zdravý Neo4j, overí existujúce indexy a podľa -potreby ich koordinovane vytvorí. Až potom spustí API a počká na readiness. -Pri opakovanom spustení ponechá konzistentné a aktuálne indexy. - -Model aj tokenizér sú súčasťou image v `/opt/zp-assets`. Bežný štart -nevyžaduje internet ani existujúcu používateľskú Hugging Face/tiktoken cache. -Prvý build potrebuje balíky a modelové súbory; build overuje aj načítanie -pripravených assets so zakázanou sieťou. Prázdny HF cache volume neskrýva -model pribalený v image. Git pripojenie je samostatná sieťová operácia; -príznaky offline zakazujú sťahovanie modelu, nie synchronizáciu wiki. - -Voliteľne môžeš pred buildom pripraviť ignorované lokálne podklady a využiť -už stiahnutý model z hostiteľa: - -```bash -.venv/bin/python -m tools.runtime.runtime_assets prepare -``` - -`runtime_assets/` obsahuje veľké modelové súbory a do Gitu nepatrí; verzovaný -je iba prázdny adresár pre čistý build. Bez pripravených lokálnych podkladov -si ich Docker build vytvorí sám. Súbory majú manifest so SHA-256 a model je -pripnutý na konkrétny commit. Iný model/revízia vyžaduje nový build s -`EMBEDDING_MODEL`/`EMBEDDING_REVISION` a zodpovedajúce pripravené assets. -API pri nesúlade neprejde potichu na sťahovanie iného modelu. - -Kontrola služby: - -```bash -curl http://127.0.0.1:8000/health -``` - -OpenAPI schéma: - -```text -http://127.0.0.1:8000/openapi.json -``` - -Logy: - -```bash -./scripts/compose.sh logs -f zp-agent-api -``` - -Zastavenie: - -```bash -./scripts/compose.sh down -``` - -Hugging Face cache volume zostáva persistentné; predvolený embeddingový -model a tokenizér však štartujú priamo z overených súborov v image. - -Neo4j je spustené ako samostatná služba v rovnakom Docker Compose -prostredí. Stav služieb je možné skontrolovať: - -```bash -./scripts/compose.sh ps -``` - -Neo4j Browser je lokálne dostupný na: - -```text -http://127.0.0.1:7474/browser/ -``` - -Kontrola spojenia z API kontajnera: - -```bash -./scripts/compose.sh exec zp-agent-api \ - python -m tools.graphrag.neo4j_smoke -``` - -## Reindexovanie - -Spoločná synchronizácia pripraví dokumenty, chunky, SQLite/FTS5, embeddingy -a Neo4j graf z jedného snapshotu wiki. Nová generácia sa aktivuje až po -úspešnej príprave oboch indexov: - -```bash -./scripts/compose.sh run --rm zp-agent-api python -m tools.rag.rebuild_index -``` - -Vzniknú súbory: - -```text -data/documents.json -data/chunks.json -data/zp_index.sqlite -data/index_version.json -``` - -Databáza obsahuje dokumenty, chunky, FTS5 index, metadata a embeddingy. - -Manuálny `/sync`, push webhook a uvedený CLI príkaz používajú rovnakú pipeline. -SQLite, Neo4j a odpovede nástrojov evidujú spoločnú verziu dát a Git revíziu. -Pri krátkom prepnutí sa nové vyhľadávanie dočasne odmietne; chyba grafu -vyvolá rollback. Pri nedokončenom prepnutí po páde zostane vyhľadávanie -nedostupné do úspešného opakovania synchronizácie. Podrobnosti a zotavenie: -Implementácia je v [tools/sync/sync_indexes.py](tools/sync/sync_indexes.py). - -## Publikovanie a dostupnosť nástrojov - -Oba nástroje predvolene vylučujú iba explicitné `published=false`. -Chýbajúca hodnota sa považuje za publikovanú. Parameter -`published_only=false` výslovne zahrnie aj nepublikované dokumenty pri -autorizovanom volaní; CLI používa `--include-unpublished`. - -`/health` uvádza samostatne `tools.rag`, `tools.neo4j` a `tools.graphrag`. -Globálne `ready` vyžaduje oba vyhľadávacie nástroje; pri výpadku Neo4j -môže klient ďalej používať RAG podľa `tools.rag.ready`. -Spoločná politika je v [tools/retrieval/publication.py](tools/retrieval/publication.py). - -## Hybridné vyhľadávanie - -RAG aj GraphRAG používajú spoločné polia `status`, `reason`, `sources`, -`index_version`, `complete`, `truncated` a `truncation_reasons`. Pôvodný -RAG kontext aj grafové fakty a cesty zostávajú dostupné. Úplnosť vyhľadania -sa odlišuje od pravdivosti odpovede; pri RAG môže byť nezaručená (`null`). -Typované polia a chyby definuje -[tools/retrieval/retrieval_contract.py](tools/retrieval/retrieval_contract.py). - -Vyhľadávanie kombinuje: - -```text -dotaz -├── FTS5 / BM25 -└── embeddingové vyhľadávanie - ↓ - RRF fusion - ↓ - lexical anchor - ↓ - výsledky -``` - -FTS5 používa stratégie: - -```text -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: - -```bash -./scripts/compose.sh run --rm zp-agent-api \ - python -m tools.rag.search_db "rag agent" --limit 5 -``` - -Pred volaním API načítaj premenné z `.env`: - -```bash -set -a -source .env -set +a -``` - -Vyhľadávanie cez zabezpečené API: - -```bash -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": true, - "max_per_document": 1 - }' -``` - -API používa hybridný engine: - -```text -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 -`tools/rag/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: - -```bash -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": true, - "max_per_document": 1 - }' -``` - -## GraphRAG - -GraphRAG vetva rozširuje existujúci klasický RAG o knowledge graph. -Graf sa vytvára deterministicky z už pripravených dokumentov a chunkov -a ukladá sa do Neo4j. - -Aktuálne používané hlavné typy uzlov: - -```text -Person -Document -DocumentAuthor -Thesis -Work -Keyword -Topic -Category -``` - -Hlavné vzťahy zahŕňajú napríklad: - -```text -Person -[:HAS_DOCUMENT]-> Document -Person -[:AUTHORED]-> Thesis -Person -[:HAS_WORK]-> Work -Thesis/Work -[:EVIDENCED_BY]-> Document -Document -[:HAS_KEYWORD]-> Keyword -Document -[:IN_CATEGORY]-> Category -DocumentAuthor -[:AUTHORED_DOCUMENT]-> Document -Document -[:DESCRIBES]-> Topic -``` - -Knowledge graph sa vytvorí príkazom: - -```bash -./scripts/compose.sh exec zp-agent-api \ - python -m tools.graphrag.build_graphrag -``` - -Builder vytvára constraints, zapisuje uzly a vzťahy a pri štandardnom -spustení obnoví iba časť grafu spravovanú ZP Agentom. Zmazanie aj zápis -prebiehajú v jednej transakcii s kontrolou počtov, takže chyba zachová -pôvodný graf. Opakované spustenie nevytvára duplicitné uzly. - -Graf je možné vizuálne kontrolovať v Neo4j Browseri. Samostatné -grafové vyhľadávanie je implementované v `tools/graphrag/graph_search.py`. -GraphRAG zatiaľ nezasahuje do stabilného klasického `/rag` toku; ďalšia -etapa spojí grafové výsledky s klasickým RAG a OpenWebUI nástrojom. - -Aktuálna evaluácia GraphRAG **v7** má DEV **1 046/1 046** a nový TEST -**80/80** pre grafové vyhľadávanie aj finálne odpovede. Modelový DEV má -**46/46**; pri novom TESTe prešlo na prvý pokus **77/80 (96,25 %)**, -po jednej povolenej oprave **80/80 (100 %)**. Prirodzený text sa skladá -z overených štruktúrovaných tvrdení. Sú to nové kombinácie nad známym -korpusom a šablónami, nie neznáme osoby ani ľudsky anotovaný benchmark. -Samostatná historická regresia má **319/320 (99,69 %)**; nepodložená -odpoveď v zostávajúcom prípade bola odmietnutá pred doručením. - -Pri zmrazení v7 prešli vtedajšie testy vrátane živých. V7 opravuje ignorovanie rokov -mimo 20xx, kontrolu rozporných tvrdení o úplnosti, počtov, povinných tvrdení -a citácií vrátane referenčného Markdownu a HTML. Začiatok štúdia vyžaduje -explicitný zdroj, neodvodzuje sa z adresára; opravilo sa 10 očakávaní. -Všetky v1–v6 merania ostávajú zachované. -[Uložené výsledky v7](tools/graphrag/evaluation/results/final_v7_2026-10-26/summary.json) -obsahujú metriky; historické manifesty a raw odpovede ostávajú pri meraniach. - -Historická v4 mala grafový strict TEST 320/320, doplnkovú kontrolu kontextových -faktov 319/320 a LLM TEST 281/300 (93,67 %). Pôvodné otázky aj výsledky -v1–v4 zostávajú zachované. Aktuálne skóre nie je zárukou všeobecnej pravdivosti. -V7 benchmark nie je nezávisle anotovaný človekom. Nové ladenie na známych -otázkach sa označuje ako regresia, nie ako nový nezávislý TEST. - -## OpenWebUI - -Pripravená kontrolovaná cesta používa samostatný Pipe v -[tools/answers/openwebui_pipe.py](tools/answers/openwebui_pipe.py). -Administrátor v **Admin Panel → Functions → Create** vloží celý súbor, -uloží ho napríklad ako `zp_verified` a aktivuje. Vo **Valves** nastaví: - -| Pole | Hodnota | -|---|---| -| `BACKEND_URL` | Adresa API dostupná zo servera OpenWebUI, bez `/answer` | -| `BACKEND_API_KEY` | Hodnota `SEARCH_API_KEY` backendu | -| `DEFAULT_ENGINE` | `rag` | -| `TIMEOUT_SECONDS` | `300` | - -Backend používa `OPENWEBUI_API_KEY` pre generujúci model. -`ANSWER_LLM_URL` je predvolene `https://ui.tukekemt.xyz/api/chat/completions` -a `ANSWER_MODEL` je `model120-fast`. Základný model nesmie odkazovať na -tento Pipe, aby nevznikla slučka. Kľúče patria do `.env` alebo Valves. -Po aktivácii sú vo výbere dva modely: overený RAG a overený GraphRAG. -Pipe odovzdáva poslednú otázku; kontextové odkazy na predchádzajúce správy -zatiaľ samostatne nerozvíja. - -Tok: **Pipe → autorizovaný `/answer` → retrieval → generovanie → kontroly -→ renderer → priamy text v UI**. Vyžaduje `accepted_for_delivery=true`; -odmietnutý text ani opravné pokusy sa nezobrazia. Iný model finálny text -neprepisuje. Inštalácia na školskom serveri čaká na administrátora a -sieťové sprístupnenie API. `localhost` vo funkcii znamená server OpenWebUI, -nie vývojový počítač. V spoločnej Compose sieti môže byť URL -`http://zp-agent-api:8000`. - -Pôvodný OpenAPI Tool Server poskytuje podklady cez `/rag`. - -OpenWebUI používa OpenAPI schému ZP Agent API a Bearer autentifikáciu -pre vyhľadávací/RAG nástroj. - -Tok požiadavky: - -```text -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`. Táto pôvodná cesta s voľným následným generovaním sama -nezaručuje kontroly doručenia pripraveného Pipe. - -## Samostatné RAG a GraphRAG Tools pre OpenWebUI - -| Nástroj | Zdroj na Gite | Funkcia | Backend | -|---|---|---|---| -| ZP Wiki RAG | [rag/tool.py](packages/openwebui/rag/tool.py) | `retrieve_zpwiki_context(query)` | `POST /rag` | -| ZP Wiki GraphRAG | [graphrag/tool.py](packages/openwebui/graphrag/tool.py) | `retrieve_zpwiki_graph(query)` | `POST /graphrag` | - -Oba sú natívne **Tools**, ktoré model môže zavolať počas odpovedania. -Pipe opísaný vyššie je samostatná funkcia na riadené doručenie odpovede. -Nový autorizovaný `/graphrag` používa rovnaký API kľúč a chybový kontrakt -ako `/rag`. Zostáva mimo pôvodnej OpenAPI schémy, ktorú existujúci RAG -klient používa bez zmeny. - -### Vytvorenie inštalovateľných balíkov - -```bash -.venv/bin/python scripts/build_tool_packages.py -``` - -Vzniknú `data/tool_packages/zpwiki_rag.json`, `zpwiki_graphrag.json` -a príslušné ZIP archívy. JSON je zoznam objektov vo formáte importu -Tools v OpenWebUI 0.9.4: ID, názov, Python kód, metadáta a prázdne -prístupové granty. Neobsahuje kľúče ani používateľské údaje. -ZIP obsahuje tento importný JSON ako `openwebui-tool.json`, `tool.py`, -`config.example.json`, `valves.schema.json`, návod `INSTALL.txt` a manifest -SHA-256 jednotlivých súborov. Opakovaný build v rovnakom prostredí je -deterministický. Zdrojové súbory a builder sú na Gite; vygenerované -archívy, importné JSON a kontrolné výstupy ostávajú ignorované v `data/`. - -### Inštalácia každého nástroja - -1. V OpenWebUI otvorte **Workspace → Tools → Import** a vyberte - `zpwiki_rag.json` alebo `zpwiki_graphrag.json`. ZIP sa najprv rozbaľuje; - samotný ZIP ani `.py` nie sú súbory pre toto importné tlačidlo. -2. Alternatívne cez **Create** vložte celý obsah príslušného `tool.py`. - Pri načítaní z Gitu otvorte súbor v repozitári, kliknite na **Raw** - a použite túto URL cez import/načítanie z URL. Každý nástroj sa - inštaluje samostatne; backendový projekt netreba inštalovať do OpenWebUI. -3. Vo **Valves** daného nástroja nastavte hodnoty z tabuľky nižšie. -4. Nástroj zapnite v novom chate alebo ho pripojte k vlastnému modelu. - Použite model s podporou volania nástrojov. Pre RAG skúste otázku na - text alebo názov práce; pre GraphRAG porovnanie osôb a rokov. -5. Prístup sprístupnite iba požadovaným účtom. Importné balíky neurčujú - verejné zdieľanie; granty sa nastavujú až v školskom UI. - -Import vyžaduje povolenie Tools Import. Možnosť vytvárať kód a meniť -Valves závisí od práv účtu. Na školskom UI sa zatiaľ nič neinštaluje; -čaká sa na profesora a sieťové sprístupnenie backendu. Postupy zodpovedajú -[oficiálnej dokumentácii Tools](https://docs.openwebui.com/features/extensibility/plugin/tools/). - -### Konfigurácia Valves - -| Nastavenie | RAG | GraphRAG | -|---|---|---| -| `BACKEND_URL` | Adresa API bez `/rag` | Rovnaká adresa API bez `/graphrag` | -| `BACKEND_API_KEY` | Hodnota `SEARCH_API_KEY` | Rovnaký vyhľadávací kľúč | -| `TIMEOUT_SECONDS` | Predvolene 30, rozsah 1–120 | Predvolene 30, rozsah 1–120 | -| `LIMIT` | Predvolene 5, rozsah 1–20 | Predvolene 40, rozsah 1–100 | -| `PUBLISHED_ONLY` | Predvolene true | Predvolene true | -| `MAX_PER_DOCUMENT` | Predvolene 1, rozsah 0–10 | Nepoužíva sa | -| `MAX_ENTITIES` | Nepoužíva sa | Predvolene 8, rozsah 1–20 | - -Volanie zachová celú otázku a upraví iba vonkajšie medzery. Limit otázky -je 500 znakov. Kľúč nie je parametrom nástroja pre model ani súčasťou -importného JSON; nastavuje sa iba vo Valves. Nástroje samy negenerujú -odpovede a nepotrebujú kľúč k jazykovému modelu. - -HTTP požiadavky idú zo servera OpenWebUI. `localhost` preto neoznačuje -vývojový počítač. V spoločnej Docker sieti môže byť adresa -`http://zp-agent-api:8000`; pri školskom serveri treba dostupnú adresu -dohodnutú s administrátorom. Cesty s prefixom reverzného proxy sú podporované. -`PUBLISHED_ONLY=true` skryje iba explicitné `published=false`; chýbajúca -hodnota sa zahrnie. Hodnota `MAX_PER_DOCUMENT=0` ruší toto obmedzenie. - -### Výstup, chyby a kontroly - -Výstup je JSON so stavom, dôvodom, zdrojmi, verziou dát a úplnosťou. -RAG prenáša úsporný kontext; GraphRAG fakty, cesty, obmedzenia a agregáciu. -Podklady sa v klientovi potichu neorezávajú ani neprepisujú. Zachovajú sa -aj `no_answer` a `ambiguous`; chyba spojenia sa nevydáva za prázdny výsledok. -HTTP chyby, timeout, neplatná konfigurácia, neplatný kontrakt a odpoveď -väčšia ako 2 MiB vracajú stav `error` bez čiastočných dôkazov. Presmerovania -sa neakceptujú, aby sa kľúč neposlal na inú adresu. Diagnostika a raw chyby -nie sú vstupom modelu. - -`output_kind=retrieval_context` a `requires_final_answer_verification=true` -označujú, že nejde o schválený text odpovede. Priame zapnutie Tools pri -bežnom LLM nezaručuje faktickú správnosť jeho následnej parafrázy. -Existujúci Pipe a `/answer` naďalej vykonávajú kontrolu a renderer; -ich `accepted_for_delivery` sa nesmie obísť. Hlavný agent, ktorý bude -nástroje automaticky vyberať a riadiť finálne doručenie, je ďalší blok. - -Lokálne testy: - -```bash -.venv/bin/python -m pytest -q test/test_openwebui_packages.py -.venv/bin/python scripts/verify_project.py --git-network -``` - -Bez vytvárania reportov a logových súborov pridajte `--no-save`. -Výsledky kontrol sa vtedy zobrazia iba v termináli. Overenie zahŕňa aj -skutočné tokenové limity všetkých chunkov a embeddingových segmentov, -zachovanie obsahu pri segmentácii a úplnosť uložených vektorov. - -Testy používajú skutočný dočasný HTTP server na loopback rozhraní a -FastAPI s riadenými dátami. Overujú autorizáciu, zachovanie otázky, -zdrojov a úplnosti, chyby a timeouty, zákaz presmerovaní aj import JSON/ZIP -v izolovanom interpreteri bez backendového projektu. Externý LLM sa nevolá. - -## Retrieval evaluácia - -Frozen retrieval benchmark sa spúšťa napríklad: - -```bash -python -m tools.rag.evaluation.evaluate_retrieval \ - --split dev \ - --strict-dataset -``` - -Podporované režimy: - -```text -dev -test -all -``` - -Vyhodnocujú sa samostatne: - -```text -FTS -vector -hybrid -``` - -a metriky: - -```text -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: - -```bash -python -m tools.rag.evaluation.evaluate_rag_answers --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: - -```text -tools/rag/evaluation/json_files/rag_answer_overrides.json -``` - -Pôvodný frozen `questions.json` tým ostáva nezmenený. - -## Tokenové limity, segmenty a embeddingová cache - -Chunkovanie dodrží `CHUNK_MAX_TOKENS` aj pri dlhom slove, riadku kódu, -tabuľke alebo nadpise. Posledné delenie zachová Unicode znaky a obsah; -celá cesta nadpisov zostáva v metadátach. - -Finálny embeddingový vstup obsahuje názov, autora, tagy, kategórie, obsah -aj prefix `passage: `. Jeho veľkosť sa meria skutočným tokenizérom modelu -vrátane špeciálnych tokenov. Nadlimitný vstup sa bez straty obsahu rozdelí -na segmenty. Pôvodný chunk, FTS a graf ostávajú zachované. Vektorové -vyhľadávanie vyberá najlepšiu zhodu segmentu a každý chunk vráti iba raz. -Encoder nadlimitný nesegmentovaný vstup odmietne namiesto tichého orezania. - -`data/embedding_cache.sqlite` uchováva vektory podľa presného vstupu a -odtlačku váh, tokenizéra a konfigurácie modelu. Pri zmene relevantných -metadát alebo modelu sa vektor prepočíta. Kontrolný súčet zachytí poškodený -záznam cache. Prvé vytvorenie novej cache prepočíta všetko; ďalšia obnova -nezmenených vstupov použije cache. Výsledok synchronizácie obsahuje -`embedding_segments`, `embedding_computed` a `embedding_reused`; počet -`embedding_chunks` stále označuje počet pokrytých pôvodných chunkov. -Cache je obnoviteľná optimalizácia; jej odstránenie pri zastavenej -synchronizácii vyvolá nový výpočet, nezmení aktívne indexy. - -`POST /rag` predvolene vracia dôkazy iba raz v `context` a stručné citačné -metadáta v `sources`. Diagnostické expanzie a ich texty sa vrátia len pri -explicitnom `include_diagnostics: true`, oddelene v `diagnostics`. -RAG evaluačný klient diagnostiku pred odoslaním modelu vždy odstráni. - -`RAG_LLM_MAX_TOKENS` (predvolene 12000) obmedzuje celý JSON podkladu -vrátane kontextu, pokynov, zdrojov a verzie dát. Nie je to rozpočet celej -konverzácie ani výstupu modelu. `RAG_LLM_TOKEN_ENCODING` má predvolene -`cl100k_base`; ide o explicitný odhad, nie presný tokenizér všetkých -vzdialených modelov. Výstup `context_budget` uvádza použitý tokenizér, -limit a skutočný počet podľa tohto odhadu. Pri orezaní nástroj nastaví -`complete=false`, `truncated=true` a dôvod `llm_context_budget`. - -## Manuálna synchronizácia a stav úloh - -`POST /sync` uloží požiadavku do persistentnej fronty a ihneď vráti HTTP 202. -Indexovanie prebieha na pozadí; prijatie požiadavky ešte neznamená dokončenie. - -```bash -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": true}' -``` - -Odpoveď obsahuje `job_id` a `status_url`, napríklad `/sync/jobs/`. -Stav načítaj rovnakým `SYNC_API_KEY`: - -```bash -curl http://127.0.0.1:8000/sync/jobs/ -H "X-API-Key: $SYNC_API_KEY" -curl http://127.0.0.1:8000/sync/status -H "X-API-Key: $SYNC_API_KEY" -``` - -Úloha má stav `queued`, `running`, `succeeded` alebo `failed`. Pole `phase` -rozlišuje čakanie na zámok, Git, budovanie a publikovanie indexov. Úspešná -úloha obsahuje v `result` počty, trvanie a spoločnú verziu SQLite a Neo4j. -Prehľad obsahuje aktívne úlohy, posledný úspech a posledné zlyhanie. - -Fronta `data/sync_jobs.sqlite` prežije reštart. Procesový zámok povoľuje -iba jedného pracovníka; rozpracovaná úloha sa po páde zopakuje. Push prijatý -po začiatku obnovy vytvorí následnú úlohu. Ďalšie čakajúce požiadavky sa -zlúčia, pričom požiadavka na stiahnutie z Gitu sa zachová. Konflikt s CLI -obnovou spôsobí čakanie, nie stratu požiadavky. Bežná chyba sa skúsi najviac -trikrát; následne zostane viditeľný stav `failed` a možno poslať nový `/sync`. -CLI `python -m tools.rag.rebuild_index --pull` zostáva synchronný. - -## Gitea webhook a prístup ku Gitu - -Endpoint `POST /webhook/gitea` overuje HMAC-SHA256 nad pôvodným telom, -veľkosť payloadu, udalosť `push`, repozitár a konkrétnu vetvu z `ref`: - -```dotenv -EXPECTED_GITEA_REPOSITORY=jp170na/zpwiki -EXPECTED_GITEA_BRANCH=master -WEBHOOK_PULL_GIT=true -``` - -Push inej vetvy a zmazanie vetvy sa ignorujú bez obnovy. `X-Gitea-Delivery` -zabraňuje opakovanému zaradeniu rovnakého doručenia. Platný push vráti HTTP -202 s odkazom na stav úlohy; nečaká na dokončenie indexovania. - -Git aktualizácia overí zhodu `origin` s očakávaným repozitárom, aktívnu -vetvu a neprítomnosť lokálnych zmien vrátane nesledovaných súborov. Potom vykoná: - -```bash -git fetch --no-tags --no-recurse-submodules origin refs/heads/master:refs/remotes/origin/master -git merge --ff-only refs/remotes/origin/master -``` - -Cieľom je aktuálna verzia nakonfigurovanej vetvy; oneskorený webhook -neprepína wiki naspäť na starší commit. Odlišná história sa automaticky -neprepisuje. Pri chybe Gitu zostávajú predchádzajúce indexy zachované. - -Pre tento wiki server treba SSH. V `.env` nastav absolútne hostiteľské cesty -`ZPWIKI_SSH_KEY` a `ZPWIKI_KNOWN_HOSTS`. Compose pripája iba tieto dva súbory -na čítanie do `/run/secrets/`; kľúč sa nekopíruje do image ani repozitára. -Použi kľúč s prístupom k wiki, ideálne deploy kľúč iba na čítanie, a vopred -over záznam servera v `known_hosts`. SSH používa `BatchMode` a povinné -striktné overenie servera; pri chybe si interaktívne nepýta heslo. - -Na Gitea nastav push webhook na verejne dosiahnuteľnú adresu -`https:///webhook/gitea` s rovnakým `WEBHOOK_SECRET`. Lokálna -adresa `127.0.0.1` nie je zo vzdialeného Gitea servera dosiahnuteľná. - -## Bezpečnosť - -Vyhľadávanie podporuje API key: - -```text -X-API-Key: -``` - -aj Bearer autentifikáciu: - -```text -Authorization: Bearer -``` - -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í: - -```bash -pip install -r deployment/requirements-dev.txt -``` - -Bežné automatizované testy: - -```bash -pytest -q -``` - -Kompletná lokálna kontrola s bežiacim projektom a `.env`: - -```bash -.venv/bin/python scripts/verify_project.py --git-network -``` - -Skript skompiluje všetky Python súbory v aplikácii, nástrojoch, balíkoch, testoch -a skriptoch, overí interné importy a syntax shell skriptov, Git, -Compose, API, spoločnú verziu indexov, integritu SQLite a kompletnú -regresiu vrátane lokálneho Neo4j. Prepínač `--git-network` navyše iba -načíta hlavičku nastavenej wiki vetvy cez existujúce SSH pripojenie. -Počas pytestu sú externé spojenia zablokované a kľúč generujúceho modelu -odstránený. HTTP transport testy povoľujú iba svoj dočasný loopback port. -Výsledky ostávajú lokálne v `data/reports/verification/` a pytest logy -v `data/logs/verification/`. Každé spustenie má vlastný časový identifikátor; -existujúci report sa neprepisuje. Skript počká najviac 90 sekúnd na -pripravenosť API po štarte Dockera (`--wait-ready-seconds`). - -### Reporty, logy a uchovávanie - -Prevádzkové indexy `documents.json`, `chunks.json`, `index_version.json`, -SQLite databázy a zámky ostávajú priamo v `data/`. Reporty sa zapisujú -do `data/reports//`, logy do `data/logs/`. Výstupy inštalovateľných -nástrojov zostávajú v `data/tool_packages/`. - -Päť najnovších dokončených kontrol projektu zostáva v aktívnom priečinku; -staršie kontroly aj ich logy sa presunú do `archive/verification/`. -Neúspešná dokončená kontrola sa tiež uchová. Rozpracované reporty sa -automaticky nearchivujú. Staršie pôvodné výstupy sú v `archive/legacy/`. -Súbory sa nemažú a ich obsah sa nemení; `data/reports/migrations/` -obsahuje záznam pôvodnej a novej cesty spolu s SHA-256. Replay klienti -vedia cez tento záznam načítať aj presunutý vstup. - -```bash -.venv/bin/python scripts/manage_reports.py # náhľad presunov -.venv/bin/python scripts/manage_reports.py --apply # presun, bez mazania -``` - -Formálne evaluačné výsledky v `tools/*/evaluation/results/`, baseline, -GraphRAG verzie a podklady pre diplomovku sa týmto uchovávaním nemenia. -RAG merania, audity a modelové odpovede v `reports/` sa automaticky -nemažú ani nerotujú; uchovávajú sa kvôli reprodukcii. Celé `data/` zostáva -ignorované Gitom. Parametre `--output` kontrolných skriptov sú voliteľné; -staré ploché cesty `data/nazov.json` sa presmerujú do príslušnej oblasti. - -### Širšie overenie kontrolovaného RAG - -`tools/rag/evaluation/json_files/verified_rag_regression.json` obsahuje -vopred vybraných 80 známych otázok z deviatich kategórií, vrátane 10 -neodpovedateľných otázok a 52 otázok s typovanými očakávaniami. -Je to regresná vzorka; jej úspešnosť nie je nový nezávislý odhad presnosti. -Očakávania overuje oddelený oracle priamo z pôvodných Markdownov. -Zdrojové cesty, odtlačky a pôvod akademického roku sú uložené pri otázkach. -Ľudská anotácia sa tým nenahrádza. Dve otázky na Dária Lindvaia používajú -rok z kategórie `dp2021`; kontrolovaná cesta taký rok nepovažuje za -explicitný dôkaz roku práce. Táto neistota je uvedená v datasete. - -```bash -# Len lokálne vyhľadávanie a kontrola podkladov, bez generujúceho modelu: -.venv/bin/python -m tools.answer_evaluation.evaluate_verified_rag --mode retrieve - -# Úmyselné chybné odpovede na uložených skutočných kontextoch, bez LLM: -.venv/bin/python -m tools.answer_evaluation.check_verified_rag_guards --input - -# Skutočné generovanie cez /answer: vyžaduje nakonfigurovaný model a povolené -# odoslanie otázok aj wiki podkladov tomuto poskytovateľovi: -.venv/bin/python -m tools.answer_evaluation.evaluate_verified_rag --mode deliver - -# Opätovné vyhodnotenie uložených odpovedí bez nového generovania: -.venv/bin/python -m tools.answer_evaluation.evaluate_verified_rag --mode replay --input -``` - -Aj evaluačný runner podporuje `--no-save`; v tomto režime otázky a odpovede -spracuje v pamäti a vypíše skóre bez zápisu reportu či deklarácie. -Kontrolovaná cesta používa pri všeobecných otázkach iba doslovné výňatky -bez nežiadaných akademických tvrdení. Referenčný odkaz v citovanom texte -sa prijme iba vtedy, keď je doložený tým istým dodaným zdrojom; položky -`source_urls` naďalej označujú pôvodné wiki zdroje. - -Runner posiela na backend iba otázku a parametre; očakávané odpovede model -nedostane. Vyhodnocuje finálny stav, prijatie odpovede, citácie, úplné -väzby osoba–práca–typ–rok a pokrytie očakávaných údajov vo výňatkoch. -Nesprávne „nenájdené“, blokované odpovede a technické zlyhania sú vedené -samostatne a zostávajú v menovateli. Doslovná citácia sama osebe nedokazuje -relevantnosť. Automatická kontrola pokrytia známych údajov nenahrádza -ľudské posúdenie významu všeobecných odpovedí. - -Kontrola syntaxe najdôležitejších upravovaných modulov: - -```bash -python -m py_compile \ - tools/rag/rag_utils.py \ - tools/rag/evaluation/evaluate_rag_answers.py \ - tools/rag/evaluation/rag_runner.py \ - tools/rag/evaluation/rag_metrics.py -``` - -Pred checkpointom je vhodné použiť aj: - -```bash -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. - -## Experimentálne datasety - -Pre ďalšie experimenty sú pripravené: - -```text -questions_extended.json -graphrag_questions.json -robustness_questions.json -performance_queries.json -``` - -`graphrag_questions.json` je aktuálne určený pre vývoj GraphRAG vetvy. -Ostatné datasety zostávajú oddelené od priebežného ladenia frozen -klasického baseline. - -## Najbližší postup - -Klasický RAG a GraphRAG sú oddelené do samostatných komponentov v -`tools/rag/` a `tools/graphrag/`. Stabilný klasický RAG zostáva -referenčným bodom. - -### 1. GraphRAG dátový model - -Model je implementovaný. Rozlišuje autora dokumentu, študenta, záverečnú -prácu, projekt, tému a kľúčové slovo. Študijný program sa nedopĺňa bez -spoľahlivého zdroja. - -### 2. GraphRAG evaluácia - -V7 má zmrazený graf, DEV **1 046/1 046** a nový TEST **80/80**. -[Finálne metriky](tools/graphrag/evaluation/results/final_v7_2026-10-26/summary.json) -oddeľuje nový TEST od historickej regresie a vyhľadávanie od modelu -s kontrolami a rendererom; pôvodné v1–v6 sa nemenia. -Pred formálnym porovnaním s klasickým RAG potrebujeme spoločnú metodiku -a ideálne otázky anotované nezávislým človekom. Nový nezávislý TEST vyžaduje -nové otázky; opakované meranie odhalených otázok je regresia. - -### 3. OpenWebUI nástroje - -Samostatné zdroje sú v `packages/openwebui/rag/` a `graphrag/`. -Builder vytvára importné JSON a ZIP s konfiguráciou, schémou a odtlačkami; -komunikácia s backendom má lokálne HTTP testy. Inštalácia na školskom -OpenWebUI čaká na oprávnenia a dostupnosť backendu. - -### 4. Hlavný agent - -Pridať hlavný prompt/agenta, ktorý podľa otázky vyberie vhodný nástroj a -bude vedieť kombinovať ich výsledky. - -### 5. Git MCP server - -Pridať samostatný MCP server pre prácu s Git repozitárom a spúšťať ho v -Dockeri. Následne ho sprístupniť hlavnému agentovi ako ďalší nástroj. - -### 6. Spojenie GraphRAG s klasickým RAG - -Po stabilizovaní grafového vyhľadávania spojiť výsledky grafu s -existujúcim FTS5 + embedding vyhľadávaním a porovnať klasický RAG s -GraphRAG variantom. - -### 7. Finálne experimenty - -Až po stabilizovaní celého systému vykonať širšie porovnanie embedding -modelov, robustnosti, výkonu a ostatných finálnych experimentov. +Projekt vzniká v rámci práce **Agent pre manažment záverečných prác**. +Spracúva profily študentov, zadania a poznámky zo ZP Wiki a poskytuje +odpovede o prácach, projektoch, rokoch a súvisiacich vzťahoch so zdrojovými odkazmi. + +## Ako funguje + +1. Načíta Markdown dokumenty a YAML metadáta z lokálnej kópie Git repozitára. +2. Rozdelí obsah na tokenové úseky a vytvorí textový, vektorový a grafový index. +3. Podľa zvoleného nástroja vyhľadá relevantné texty alebo grafové fakty. +4. Jazykový model vyberie dôkazy alebo navrhne štruktúrované tvrdenia. +5. Backend skontroluje hodnoty, väzby, citácie a pokrytie požadovaných údajov. +6. Z overených podkladov zostaví odpoveď; chýbajúce informácie výslovne označí. + +Aktualizáciu možno spustiť manuálne alebo webhookom z Gitea. Oba indexy +sa obnovujú z rovnakého snapshotu a používajú spoločnú verziu dát. + +## Vyhľadávanie + +**RAG** kombinuje fulltextové vyhľadávanie BM25 so sémantickým vyhľadávaním +pomocou embeddingov. Výsledky spája metódou RRF. Je vhodný na otázky +na obsah, zadanie, metódy, priebeh a výsledky práce. + +**GraphRAG** využíva znalostný graf osôb, dokumentov, prác, projektov, +tém, tagov a kategórií. Umožňuje vyhľadávať vzťahy, spoločné vlastnosti +a kombinácie podmienok, napríklad tag spolu s typom a rokom práce. + +## Použité technológie + +- **Python, FastAPI a Pydantic** – API, validácia vstupov a typované odpovede. +- **SQLite a FTS5** – dokumenty, metadáta, fulltextový index a uložené vektory. +- **Sentence Transformers a multilingual-e5-small** – viacjazyčné embeddingy. +- **Tiktoken** – meranie veľkosti a delenie textových úsekov. +- **Neo4j a Cypher** – uloženie a vyhľadávanie grafových vzťahov. +- **MCP a Claude Skills** – sprístupnenie RAG a GraphRAG používateľovi v Claude. +- **OAuth s PKCE** – autentizácia webového MCP konektora. +- **Docker Compose** – spoločné nasadenie API, Neo4j a MCP servera. +- **Git a Gitea webhooky** – získavanie zmien a spúšťanie synchronizácie. +- **Pytest a evaluačné skripty** – regresie, kontrola vyhľadávania a odpovedí. + +## Súčasný stav + +RAG, GraphRAG, kontrolovaná cesta odpovedí a pripojenie cez Claude sú funkčné. +Systém obsahuje embeddingovú cache, kontroly dostupnosti a persistentnú +synchronizačnú frontu. Historické evaluácie sú uložené pri jednotlivých vetvách. +Samostatný hlavný agent, CRZP a spracovanie plných textov prác sú ďalšie etapy.