Changelog
Všechny podstatné změny projektu GMS Asistent (chatbot pro vyhledávání zboží
na gms.cz). Formát dle Keep a Changelog.
Konvence: každý release má verzi + datum a čas (Europe/Prague). Časy F1–F3
odpovídají git commitům.
[0.5.2] – 2026-06-19 17:28 – Changelog na webu, UI drobnosti
Added
- Changelog na webu: stránka
/changelog(renderujeCHANGELOG.md,
app/mdrender.py – minimální Markdown→HTML bez závislostí). Odkazy
„Changelog" a „Admin" v hlavičce chatu.
Změněno
- Indikátor psaní v chatu: „typuji…" → „Přemýšlím…".
Pozn. (infrastruktura)
- Cron pro obnovu certu zúžen na
--cert-name gms.x86.cz(neplete se do NPM
certů); dry-run obnovy gms.x86.cz = success.
[0.5.1] – 2026-06-19 17:23 – Recall a HTTPS
Zlepšeno
- Recall vágních dotazů: pro sémantiku se embeduje kombinace čisté fráze
od LLM (dobrá diakritika) + celého dotazu (zachová kontext jako teplota/médium).
„najdi hadici na benzin" → opět 5 výsledků (dřív 1); „pryž nad 150 °C" → 5.
Ověřeno cílenými testy (benzín/polyamid/pryž 150°C/voda = 5, banán = 0).
Nasazení
- HTTPS na gms.x86.cz hotové ✅ – Let's Encrypt cert (certbot webroot v NPM),
443 SSL blok + redirect 80→443 v nginx-proxy-manager:/data/nginx/custom/http.conf.
Ověřeno z internetu: https://gms.x86.cz → 200, http → 301. Cert expiruje
2026-09-17, automatická obnova přes cron na droidu (certbot renew + reload).
[0.5.0] – 2026-06-19 17:06 – F4: Relevance přes evaluaci 55 otázek, robustnost, TEST/rproxy
Zlepšeno (iterativně přes scripts/eval2.py – 55 reálných zákaznických otázek po kategoriích)
- on_topic doména rozšířena podle skutečných kategorií GMS (pryže, gumové/
těsnící desky, podlahoviny, profily, tyče, technické plasty) – přestaly se
chybně zahazovat dotazy typu „polyamidová tyč", „pryž nad 150 °C".
- Sémantika embeduje PŘIROZENÝ dotaz (historie + zpráva), ne LLM-keywordy →
spolehlivější relevance (false-negativy zmizely).
- Poradenské dotazy (rozdíl materiálů, jak vybrat, na míru): když není přesný
produkt, LLM poradí obecně a doptá se (bez výmyslu produktů). Mimo-obor →
stručná hláška bez volání LLM.
- Max 5 produktů (tvrdý strop), klidně méně (práh relevance ořeže slabé).
Robustnost
- Ošetření 429 (rate limit TPM): OpenAI i Anthropic klient
max_retries=6
(automatický exponenciální backoff, respektuje retry-after); zmenšen prompt
odpovědi (méně tokenů). Eval harness má pacing.
Výsledky evaluace (55 otázek, LLM-soudce spokojenosti)
| baseline | po iteracích | |
|---|---|---|
| spokojenost | 3.73/5 | 4.20/5 (+12,6 %) |
| slabé odpovědi (≤2/5) | 12 | 1 |
| nejslabší kategorie | Plasty 2.0, Pryže 3.3 | vše ≥ 4.0 |
Nasazení / infrastruktura
- rproxy hotová: http://gms.x86.cz/ jede (NPM custom include
/data/nginx/custom/http.conf → 192.168.254.199:45080). HTTPS = TODO
(Let's Encrypt přes NPM GUI).
- Changelog: konvence verze + datum a čas u každého releasu (časy z gitu).
[0.4.0] – 2026-06-19 15:16 – F3: Logování, admin, multi-turn, evaluace relevance
Added
- Logování diskuzí (
app/chatlog.py, tabulkachat_logs– idempotentní,
přežije re-ingestaci): každý chat se ukládá (zpráva, extrakce, výsledky, odpověď,
časy, ok/error, session_id).
- Admin rozhraní
static/admin.htmlna/admin+ endpointy/api/logs,
/api/logs/{id} (chráněné DEBUG_PASSWORD): procházení diskuzí, detail,
filtr podle session, „Kopírovat odkaz na log", deep-linky.
- Paměť diskuze (multi-turn): server kumuluje kontext podle
session_id,
LLM extrakce dostává historii → zákazník může postupně upřesňovat (5× pokračovat).
- on_topic gate: LLM rozhodne, zda je dotaz z oboru; mimo-oborové (notebook,
banán, auto) → vrací NIC (radši nic než nerelevantní).
- Laditelný práh relevance
SEARCH_MIN_SIM(env, default 0.40 – kalibrováno:
relevantní ~0.43+, nesmysly ~0.30–0.39).
scripts/eval.py– evaluační harness: 21 simulovaných diskuzí (laická i přesná
zadání, multi-turn), LLM-soudce spokojenosti.
- Odpověď obohacena o technický detail (materiál/teplota/použití z
body_text),
výpis až 5 produktů s odkazy; default limit 5.
Opraveno (přes iterace eval harness)
- Fulltext fallback se NEspouští, když sémantika nic relevantního nenašla
(dřív vracel keyword balast).
- Sémantika dostává PŘIROZENOU frázi (např. „hadice na naftu"), ne holá klíčová
slova (ta embedovala špatně) → opravena regrese vágních dotazů.
- OpenAI/Claude/Gemini extrakce: pole
on_topic, multi-turn historie.
Výsledky evaluace (21 diskuzí, LLM-soudce)
| baseline | po iteracích | |
|---|---|---|
| správné chování | 18/21 (86 %) | 21/21 (100 %) |
| spokojenost (relevantní) | 3.56/5 | 3.72/5 |
| spokojenost (celkem) | 3.48/5 | 3.71/5 |
- Strop spokojenosti drží chybějící ceny (soudce opakovaně „cena chybí")
– přijdou z plné DB.
Analýza PDF (závěr)
- Datasheety lze extrahovat (pypdf), ale jsou často v IT/EN, dokumenty jsou
smíšené (i .jpg, právní prohlášení). body_text už pokrývá podstatu.
- Plošná ingestace PDF se nedoporučuje (okrajový přínos, velká práce/OCR).
Selektivně jen pro produkty s prázdným popisem. Větší přínos = ceny + kategorie.
[0.3.0] – 2026-06-19 14:31 – F2: Sémantika, relevance, ověřeno v Dockeru
Added
app/embed.py+scripts/embed_products.py– sémantické embeddingy
(OpenAI text-embedding-3-small, 1536 dim) do products.embedding (pgvector),
HNSW index. Pro všech 5 665 produktů spočítáno.
app/search.pypřepsán na sémantické vyhledávání s prahem relevance
(MIN_SIM=0.30) – přirozený dotaz řadí embeddingy, rozměry zůstávají tvrdým
filtrem; fulltext (FTS) je fallback. → vrací jen relevantní výsledky.
- Odkaz na produkt v každém výsledku (
url) na eshopové vyhledávání
https://www.gms.cz/?query=<název>; asistent ho uvádí jako markdown odkaz.
scripts/ask.py– ruční test relevance přes API.
Ověřeno v běžícím Dockeru (PostgreSQL+pgvector)
- Ingestace partnerských feedů do Postgresu: **5 665 produktů, 45 593 SKU,
343 878 hodnot parametrů**.
- Hybrid hledání s přesným filtrem rozměrů (benzín+Ø50, silikon+Ø8, tlak≥40 bar) ✓.
- Cíl „najdi hadici na benzin" → jen relevantní palivové hadice (PETROTEC TX/
NBR/FUB/CLC…, FKM ponorná), žádné navijáky/pistole/požární hadice. ✓
- Chat end-to-end přes OpenAI i Gemini (extrakce → hledání → česká odpověď
s odkazy). Klíče v .env (negitováno).
Opraveno
- Pořadí vazby SQL parametrů v hledání (
%spoziční). - OpenAI extrakce přepnuta na striktní
json_schema(constraints jako pole). - Gemini model
gemini-2.0-flash(404) →gemini-2.5-flash. .dockerignore(image bez.venv/dat); feedy mimo image, kopírují se k ingestaci.
Pozn.
- Přímé URL produktu (slug) nejsou v partnerském feedu – dočasně odkazujeme na
eshopové hledání podle názvu; přesné URL doplníme z plné DB.
- Ceny zatím NULL (Heureka join podle názvu nesedí) – doladí se z plné DB.
[0.2.0] – 2026-06-19 14:00 – F1: Microservice (FastAPI + PostgreSQL + AI)
Rozhodnutí (odsouhlaseno zadavatelem)
- Databáze: PostgreSQL + pgvector (docker-compose, 2 kontejnery).
- AI: přepínatelní poskytovatelé Claude / OpenAI / Gemini (default Claude,
model claude-opus-4-8).
- Port služby 8040; doména gms.x86.cz přes RPROXY na PikoDroidu.
Added
db/schema.sql– PostgreSQL schéma (products/skus/params/param_dict,
pgvector embedding, tsvector fulltext s unaccent). ID jako TEXT
(katalogové kódy vč. SERVICE*, NV260347 – o žádnou položku nepřijdeme).
app/feed.py– čisté parsování partnerských feedů (testovatelné bez DB).scripts/ingest_partner.py– ingestace zbozi.xml + parametry.xml do Postgresu
přes COPY, stavba fulltextu, doplnění cen z Heureka feedu.
app/db.py– psycopg3 connection pool (lazy, app jde importovat i bez DB).app/search.py– hybrid retrieval: fulltext + PŘESNÝ strukturovaný filtr
rozměrů nad parsovanými čísly (na úrovni produktu i SKU).
app/llm.py– přepínatelná AI vrstva (Claude/OpenAI/Gemini), structured
extrakce omezení + generace odpovědi nad dohledanými daty (lazy import SDK).
app/auth.py– zabezpečení API pro e-shop: API klíč + HMAC podpis (+ replay
ochrana), volitelné heslo pro debug UI.
app/server.py– FastAPI:/api/health,/api/params,/api/search
(chráněné), /api/chat (LLM + debug info), debug UI na /.
static/index.html– debug chat rozhraní (česky) s debug panelem
(extrahované filtry, časy, nalezené produkty/SKU/rozměry).
Dockerfile,docker-compose.yml(app + pgvector),.env.example,
scripts/fetch_feeds.sh.
- Rozšířena normalizace o teploty (
-30°C až +100°C→ −30..100 °C). - Testy:
tests/test_feed.py(3) +tests/test_normalize.py(9 vč. teplot) =
12 prochází.
Ověřeno
- Všechny moduly se kompilují; aplikace nastartuje a degraduje elegantně bez DB/
klíčů (smoke test TestClient: /api/health 200, UI na /, čisté 503/502).
- Parsování partnerských feedů ověřeno na reálných datech (5 665 produktů,
45 592 SKU, 343 878 hodnot parametrů, 0 sirotků).
Čeká na zadavatele (blokuje finální ověření)
- Spustit Docker (lokálně chybí daemon) → integrační test Postgres+ingestace+
hybrid search + build image.
- GitHub auth (
gh/token chybí) → push do privátního repapikodrak/gms-asistent. - AI klíče do
.env→ ověření/api/chatend-to-end.
[0.1.0] – 2026-06-19 13:40 – F0: Průzkum a datový základ
Added
- Inicializace projektu, profesionální struktura (
app/,scripts/,data/,
docs/, static/, tests/).
- Stažen pracovní produktový feed
data/feed-raw.xml(Heureka XML, 18,8 MB). app/normalize.py– normalizace rozměrů/parametrů. Klíčový princip
„nesmí odhadovat“: uchovává raw hodnotu, numeriku parsuje jen když je
jednoznačná (rozsahy, české čárky, převod MPa/kPa→bar), jinak ponechá text.
scripts/ingest.py– ingestace feedu do SQLite (products/variants/params
+ FTS5 fulltext bez diakritiky).
tests/test_normalize.py– 9 testů normalizace (vše prochází).docs/DESIGN.md– návrh architektury (hybrid retrieval, AI vrstva,
zabezpečené API, debug UI, nasazení).
Zjištění z dat (ověřeno)
- 11 894 variant / 2 829 produktů / 75 550 parametrů / 74 typů parametrů.
- Varianty se liší hlavně rozměry → nutné přesné strukturované filtrování.
- 82,3 % parametrů bezpečně parsováno na čísla; zbytek (závity, placeholdery)
ponechán jako přesný text.
- Ověřeno: hybrid dotaz „benzín + vnitřní Ø 50 mm“ → 1 přesná shoda.
Partnerské feedy (přidáno, bohatší zdroj)
- Staženy
data/zbozi.xml(22 MB) adata/parametry.xml(27 MB). - zbozi.xml: 5 665 produktů, 45 594 objednacích kódů (SKU), dlouhé technické
popisy, 9 324 PDF datasheetů, 12 481 obrázků, vazby skupin a souvisejících.
- parametry.xml: slovník 1 638 parametrů + hodnoty pro 51 259 položek
(produkty i SKU), ø 6,7 parametru/položku.
- Ověřena vazba:
parametryid ↔ produkt/SKU zzbozi= 100 % shoda, 0 sirotků. - Závěr: partnerské feedy budou primární zdroj (F1), Heureka feed záloha + ceny.
Infrastruktura (poznámky)
- Cílová doména: gms.x86.cz na PikoDroidu (DNS hotovo). Nutno přidat záznam
na RPROXY → HTTPS do Docker kontejneru.
- Deploy a privátní GitHub repo dle vzoru
pikodrak-game-marshal-spy.