correct README.md №2

This commit is contained in:
G0DSEND016 2026-03-23 09:30:14 +01:00
parent 890957635d
commit e54b42fc04
3 changed files with 91 additions and 56 deletions

137
README.md
View File

@ -1,89 +1,132 @@
# Právny AI Asistent integrácia s API # Právny AI Asistent integrácia s API
## POPIS ## Popis
Právny AI Asistent je inteligentný asistent integrovaný s oficiálnymi verejnými API Ministerstva spravodlivosti Právny AI Asistent je inteligentný asistent integrovaný s oficiálnymi verejnými API Ministerstva spravodlivosti Slovenskej republiky. Systém poskytuje užívateľom prístup k štruktúrovaným právnym informáciám prostredníctvom prirodzeného jazyka.
Slovenskej republiky. Systém poskytuje užívateľom prístup k štruktúrovaným právnym informáciám prostredníctvom
prirodzeného jazyka.
**Hlavné funkcie:** **Hlavné funkcie:**
- Interpretácia užívateľských otázok v prirodzenom jazyku - Interpretácia užívateľských otázok v prirodzenom jazyku
- Automatická extrakcia a validácia parametrov - Automatická extrakcia a validácia parametrov
- Načítavanie dát výlučne cez oficiálne API - Načítavanie dát výlučne cez oficiálne API
- Prezentácia výsledkov v zrozumiteľnom formáte v slovenskom jazyku - Prezentácia výsledkov v zrozumiteľnom formáte v slovenskom jazyku
## POUŽITÉ KNIŽNICE A TECHNOLÓGIE ---
- **Python** hlavný programovací jazyk ## Použité knižnice a technológie
- **openai-agent** tvorba AI agentov od OpenAI
- **httpx** asynchrónna komunikácia s API ### Jadro aplikácie
- **Chainlit** framework pre chat rozhranie
- **Ollama** lokálne používanie AI modelov | Technológia | Účel |
- **Docker** kontajnerizácia aplikácie |---|---|
- a **iné** | **Python 3.11** | Hlavný programovací jazyk |
| **openai-agents** | Tvorba AI agentov a streamovanie odpovedí |
| **openai** | Python klient pre OpenAI / Ollama API |
| **Chainlit** | Framework pre chat rozhranie |
| **Ollama** | Lokálne spúšťanie AI modelov |
| **Docker** | Kontajnerizácia aplikácie |
| **python-dotenv** | Načítavanie premenných prostredia zo súboru `.env` |
### API a sieť
| Technológia | Účel |
|---|---|
| **httpx** | Asynchrónna HTTP komunikácia s API |
| **pydantic** | Validácia a serializácia vstupných parametrov (schémy) |
| **cachetools** | TTL cache pre API odpovede |
| **tenacity** | Automatické opakovanie požiadaviek pri chybách (retry) |
### Testovanie
| Technológia | Účel |
|---|---|
| **pytest** | Testovací framework |
| **pytest-asyncio** | Podpora asynchrónnych testov |
| **respx** | Mockovanie HTTP požiadaviek (httpx) |
| **pytest-html** | Generovanie HTML reportov z testov |
| **pytest-cov** | Meranie pokrytia kódu testami |
---
## Štruktúra projektu
## ŠTRUKTÚRA PROJEKTU
``` ```
ai-lawyer-agent/ ai-lawyer-agent/
├── .chainlit/ # Konfigurácia Chainlit
├── api/ # API logika ├── api/ # API logika
│ └── tools/ # API nástroje │ ├── __init__.py
│ ├── __init__.py │ ├── fetch_api_data.py # Spracovanie API
│ ├── fetch_api_data.py # Spracovanie API │ ├── config.py # Konfigurácia API
│ └── schemas.py # Pydantic schémy │ ├── schemas.py # Pydantic schémy
│ └── tools.py # API nástroje (function tools pre agenta)
├── core/ ├── core/
│ ├── __init__.py │ ├── __init__.py
│ ├── initialize_agent.py # Inicializácia AI agenta │ ├── config.py # Konfigurácia agenta (modely, parametre)
│ ├── init_agent.py # Inicializácia AI agenta
│ ├── stream_response.py # Streamovanie odpovedí │ ├── stream_response.py # Streamovanie odpovedí
│ └── system_prompt.py # Systémový prompt │ └── system_prompt.py # Systémový prompt
├── public/ # Verejné zdroje ├── public/ # Verejné zdroje
│ ├── icon/ # Ikony a logá ├── testing/ # Testy a testovacie nástroje
│ │ ├── favicon.png │ ├── tests/
│ │ ├── logo_dark.png │ │ ├── test_api.py # Integračné testy voči reálnemu API
│ │ └── logo_light.png │ │ ├── test_fetch.py # Unit testy pre fetch_api_data
│ ├── img/ │ │ ├── test_llm_compare.py # LLM benchmark testy
│ ├── styles.css # Štýly rozhrania │ │ ├── test_project.py # LLM extrakcia parametrov (DB testy)
│ └── theme.json # Nastavenia témy │ │ ├── test_schemas.py # Unit testy Pydantic schém
├── .chainlit/ # Markdown pre Chainlit │ │ ├── test_sys_prompt.py # Unit testy systémového promptu
└── app.py # Hlavný súbor aplikácie (Сhainlit + spracovanie API) │ │ └── test_tools.py # Unit testy API nástrojov
│ ├── charts/ # Výstupné reporty a coverage (generované)
│ ├── test_cases.db # SQLite databáza testovacích prípadov
│ └── run_tests.py # Spúšťač testov (pytest + HTML report + coverage)
├── app.py # Hlavný súbor aplikácie (Chainlit + spracovanie API)
├── chainlit.md # Uvítacia obrazovka (default Chainlit)
└── chainlit_en-US.md # Uvítacia obrazovka (Legal AI Assistant)
``` ```
---
## INŠTRUKCIA PRE INŠTALÁCIU ## Testovanie
Projekt obsahuje automatizované testy pokrývajúce unit testy schém, API nástrojov, fetchovania dát, systémového promptu a integračné testy voči reálnemu API Ministerstva spravodlivosti. LLM testy overujú správnosť extrakcie parametrov z prirodzeného jazyka oproti 54 referenčným prípadom uloženým v SQLite databáze.
![Test Report](testing/images/coverage_and_test_session.png)
---
### **Inštalácia cez Git** ## Inštrukcia pre inštaláciu
### 1. **Naklonovanie repozitára** ### Inštalácia cez Git
#### 1. Naklonovanie repozitára
```bash ```bash
git clone git@git.kemt.fei.tuke.sk:od059jr/ai-lawyer-agent.git git clone git@git.kemt.fei.tuke.sk:od059jr/ai-lawyer-agent.git
``` ```
### 2. **Vytvorenie virtuálneho prostredia** #### 2. Vytvorenie virtuálneho prostredia
#### Pre Windows **Windows:**
```bash ```bash
python -m venv venv python -m venv venv
venv\Scripts\activate venv\Scripts\activate
``` ```
#### Pre macOS/Linux **macOS / Linux:**
``` ```bash
python3 -m venv venv python3 -m venv venv
source venv/bin/activate source venv/bin/activate
``` ```
### 3. **Inštalácia závislostí** #### 3. Inštalácia závislostí
```bash ```bash
pip install -r requirements.txt pip install -r requirements.txt
``` ```
### 4. **Sťahovanie inštalátora Ollama** #### 4. Stiahnutie inštalátora Ollama
https://ollama.com/download Stiahnite si Ollama z oficiálnej stránky: https://ollama.com/download
#### 5. Stiahnutie modelov
### 5. **Sťahovanie modelov**
```bash ```bash
ollama pull qwen3.5:cloud ollama pull qwen3.5:cloud
@ -93,12 +136,14 @@ ollama pull qwen3.5:cloud
ollama pull gpt-oss:20b-cloud ollama pull gpt-oss:20b-cloud
``` ```
---
### **Inštalácia cez DOCKER** ### Inštalácia cez Docker
### 1. Inštalácia Docker a Docker Desktop #### 1. Inštalácia Docker a Docker Desktop
### 2. Nainštalujte a spustite aplikáciu Stiahnite a nainštalujte Docker Desktop: https://www.docker.com/products/docker-desktop
https://hub.docker.com/r/alexgott0616/ai-lawyer-agent #### 2. Nainštalujte a spustite aplikáciu
Obraz je dostupný na Docker Hub: https://hub.docker.com/r/alexgott0616/ai-lawyer-agent

View File

@ -169,9 +169,7 @@ class TestModelDumpExcludeNone:
def test_empty_schema_excludes_none_fields_only(self): def test_empty_schema_excludes_none_fields_only(self):
dumped = CourtSearch().model_dump(exclude_none=True) dumped = CourtSearch().model_dump(exclude_none=True)
# sortDirection='ASC' is a real default, not None — correctly kept
assert dumped.get("sortDirection") == "ASC" assert dumped.get("sortDirection") == "ASC"
# None fields are excluded
assert "page" not in dumped assert "page" not in dumped
assert "size" not in dumped assert "size" not in dumped
assert "query" not in dumped assert "query" not in dumped

View File

@ -143,7 +143,6 @@ class TestDecisionTools:
@respx.mock @respx.mock
async def test_decision_id_calls_correct_url(self): async def test_decision_id_calls_correct_url(self):
"""Covers missing lines 128-130 in tools.py"""
mock = respx.get(f"{JUSTICE_API_BASE}/v1/rozhodnutie/rozhodnutie_99").mock( mock = respx.get(f"{JUSTICE_API_BASE}/v1/rozhodnutie/rozhodnutie_99").mock(
return_value=httpx.Response(200, json={"id": "rozhodnutie_99"}) return_value=httpx.Response(200, json={"id": "rozhodnutie_99"})
) )
@ -152,7 +151,6 @@ class TestDecisionTools:
@respx.mock @respx.mock
async def test_decision_autocomplete_calls_correct_url(self): async def test_decision_autocomplete_calls_correct_url(self):
"""Covers missing lines 141-143 in tools.py"""
mock = respx.get(f"{JUSTICE_API_BASE}/v1/rozhodnutie/autocomplete").mock( mock = respx.get(f"{JUSTICE_API_BASE}/v1/rozhodnutie/autocomplete").mock(
return_value=make_response() return_value=make_response()
) )
@ -181,7 +179,6 @@ class TestContractTools:
@respx.mock @respx.mock
async def test_contract_id_calls_correct_url(self): async def test_contract_id_calls_correct_url(self):
"""Covers missing lines 172-174 in tools.py"""
mock = respx.get(f"{JUSTICE_API_BASE}/v1/zmluvy/2156252").mock( mock = respx.get(f"{JUSTICE_API_BASE}/v1/zmluvy/2156252").mock(
return_value=httpx.Response(200, json={"idZmluvy": "2156252"}) return_value=httpx.Response(200, json={"idZmluvy": "2156252"})
) )
@ -190,7 +187,6 @@ class TestContractTools:
@respx.mock @respx.mock
async def test_contract_autocomplete_calls_correct_url(self): async def test_contract_autocomplete_calls_correct_url(self):
"""Covers missing lines 185-187 in tools.py"""
mock = respx.get(f"{JUSTICE_API_BASE}/v1/zmluvy/autocomplete").mock( mock = respx.get(f"{JUSTICE_API_BASE}/v1/zmluvy/autocomplete").mock(
return_value=make_response() return_value=make_response()
) )
@ -211,7 +207,6 @@ class TestCivilAndAdminTools:
@respx.mock @respx.mock
async def test_civil_proceedings_id_calls_correct_url(self): async def test_civil_proceedings_id_calls_correct_url(self):
"""Covers missing lines 217-219 in tools.py"""
uid = "121e4d31-695e-41e1-9191-7c9ad5d8d484" uid = "121e4d31-695e-41e1-9191-7c9ad5d8d484"
mock = respx.get(f"{JUSTICE_API_BASE}/v1/obcianPojednavania/{uid}").mock( mock = respx.get(f"{JUSTICE_API_BASE}/v1/obcianPojednavania/{uid}").mock(
return_value=httpx.Response(200, json={"id": uid}) return_value=httpx.Response(200, json={"id": uid})
@ -221,7 +216,6 @@ class TestCivilAndAdminTools:
@respx.mock @respx.mock
async def test_civil_proceedings_autocomplete_calls_correct_url(self): async def test_civil_proceedings_autocomplete_calls_correct_url(self):
"""Covers missing lines 230-232 in tools.py"""
mock = respx.get(f"{JUSTICE_API_BASE}/v1/obcianPojednavania/autocomplete").mock( mock = respx.get(f"{JUSTICE_API_BASE}/v1/obcianPojednavania/autocomplete").mock(
return_value=make_response() return_value=make_response()
) )
@ -238,7 +232,6 @@ class TestCivilAndAdminTools:
@respx.mock @respx.mock
async def test_admin_proceedings_id_calls_correct_url(self): async def test_admin_proceedings_id_calls_correct_url(self):
"""Covers missing lines 260-262 in tools.py"""
mock = respx.get(f"{JUSTICE_API_BASE}/v1/spravneKonanie/spravneKonanie_103").mock( mock = respx.get(f"{JUSTICE_API_BASE}/v1/spravneKonanie/spravneKonanie_103").mock(
return_value=httpx.Response(200, json={"id": "spravneKonanie_103"}) return_value=httpx.Response(200, json={"id": "spravneKonanie_103"})
) )
@ -247,7 +240,6 @@ class TestCivilAndAdminTools:
@respx.mock @respx.mock
async def test_admin_proceedings_autocomplete_calls_correct_url(self): async def test_admin_proceedings_autocomplete_calls_correct_url(self):
"""Covers missing lines 273-275 in tools.py"""
mock = respx.get(f"{JUSTICE_API_BASE}/v1/spravneKonanie/autocomplete").mock( mock = respx.get(f"{JUSTICE_API_BASE}/v1/spravneKonanie/autocomplete").mock(
return_value=make_response() return_value=make_response()
) )