Obsah · Kapitola 7 · Log konverzací (MySQL)

Log konverzací (analytika v MySQL)

← Kapitola 7: Administrace a konfigurace

Modul log konverzací ukládá do MySQL text dotazu návštěvníka a text odpovědi AI po každém úspěšném chatu na kiosku. Slouží provozovateli k analýze (nejčastější témata, kvalita odpovědí, jazyková skladba návštěvníků) – není určen návštěvníkům a neobsahuje veřejné API.

Rozdíl oproti statistikám API: sekce Využití API & kredity v adminu zapisuje do usage-stats jen počty požadavků, tokeny a odhad nákladů – bez textu konverzace. Log konverzací je samostatný modul s vlastní tabulkou (výchozí název exhibit_chat_log).

1. Přehled a účel

Na veřejném kiosku návštěvník mluví do mikrofonu; prohlížeč převádí řeč na text a odešle ho na server (api.php?action=chat). Po úspěšné odpovědi AI může server – pokud je modul zapnutý – zapsat pár do MySQL. Typické využití:

  • muzeum – „na co se lidé nejčastěji ptají“, chybějící informace v expozici;
  • veletrh – ověření, zda návštěvníci chápou produkt;
  • údržba – hledání opakujících se chyb odpovědí nebo nevhodných dotazů po nasazení nového promptu.

Modul nenahrazuje znalostní bázi exponátů ani plánovaný deníček uživatele (nákupní seznam, poznámky) – ukládá průběžný dialog s avatarem, ne strukturovaná data podle příkazů uživatele.

2. Připojení MySQL a vytvoření tabulky

Předpoklady jsou stejné jako u znalostní báze:

  1. Admin → Databáze MySQL – vyplněné údaje, zaškrtnuto MySQL zapnuto, test OK.
  2. Admin → Log konverzací – zkontrolujte název tabulky (výchozí exhibit_chat_log).
  3. Pokud tabulka neexistuje: tlačítko Vytvořit tabulku v MySQL nebo ruční spuštění SQL ze souboru tools/create-chat-log.sql v databázi z configu.
  4. Zaškrtněte Ukládat dotazy a odpovědi do MySQL (anonymně) a uložte nastavení.
SQL schéma tabulky (ukázka)

Sloupce: čas, anonymní session_id, jazyk UI, provider, model, dotaz, odpověď, tokeny.

CREATE TABLE IF NOT EXISTS `exhibit_chat_log` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `session_id` CHAR(36) NOT NULL,
    `ui_lang` VARCHAR(8) NOT NULL DEFAULT 'cs',
    `provider` VARCHAR(16) NOT NULL DEFAULT '',
    `model` VARCHAR(64) NOT NULL DEFAULT '',
    `user_message` TEXT NOT NULL,
    `assistant_reply` MEDIUMTEXT NOT NULL,
    `tokens_in` INT UNSIGNED NOT NULL DEFAULT 0,
    `tokens_out` INT UNSIGNED NOT NULL DEFAULT 0,
    PRIMARY KEY (`id`),
    KEY `idx_created_at` (`created_at`),
    KEY `idx_session_id` (`session_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

3. Nastavení v administraci

Pole / akceVýznam
chat_log_enabled Zapne zápis po úspěšném chatu (vyžaduje MySQL + existující tabulku)
chat_log_table Název tabulky v databázi (výchozí exhibit_chat_log)
Vytvořit tabulku Jednorázově vytvoří tabulku podle schématu (CREATE IF NOT EXISTS)
Prohlížet záznamy Odkaz na admin-chat-log.php – jen po přihlášení do adminu

Konfigurace je v souboru config stejně jako ostatní moduly; přístup k logu nemá kiosk ani veřejné URL.

4. Co se ukládá a co ne

Ukládá seNeukládá se
  • text dotazu (user_message)
  • text odpovědi AI (assistant_reply)
  • čas serveru (created_at, UTC v DB)
  • jazyk UI z kiosku (ui_lang – CS, EN, …)
  • provider a model (Gemini / OpenAI)
  • počty tokenů (souhrn z API)
  • anonymní session_id (UUID relace na kiosku)
  • jméno, e-mail, telefon návštěvníka
  • IP adresa, MAC, identifikátor zařízení
  • audio nahrávka hlasu (ukládá se jen přepis textu)
  • heslo admina, API klíče
  • neúspěšné požadavky (chybějící klíč, quota, prázdná odpověď)

Relace (session_id): při každém „Klepněte pro start“ kiosk vygeneruje nové náhodné UUID a posílá ho s každým dotazem v té relaci. Slouží k seskupení několika otázek jednoho návštěvníka – neidentifikuje osobu a po resetu idle / novém startu vzniká nové ID.

5. Technický průběh

  1. Klient (app.js, rive.js, …) – skript exhibit-session.js vytvoří UUID při startu relace.
  2. POST na api.php?action=chat s JSON: message, history, ui_lang, session_id.
  3. Server zavolá Gemini nebo OpenAI; při úspěchu zavolá recordExhibitChatLogFromChatRequest().
  4. Zápis selže-li (DB nedostupná) – chat na kiosku pokračuje, chyba se neukáže návštěvníkovi.

D-ID varianta používá did-api.php?action=chat, ale stejnou serverovou logiku chatu – log funguá i tam. Statistiky API (usage-stats) běží paralelně a jsou nezávislé.

6. Prohlížení záznamů (jen administrátoři)

Stránka admin-chat-log.php (po přihlášení heslem do adminu) zobrazuje tabulku: čas, zkrácené session_id, jazyk, dotaz, odpověď, tokeny. Stránkování po 40 řádcích.

  • Pro hlubší analýzu exportujte data přímo z MySQL (phpMyAdmin, DBeaver, mysqldump vybrané tabulky).
  • Mazání starých záznamů aplikace automaticky neprovádí – nastavte interní politiku retence (viz GDPR níže).

7. GDPR – povinnosti provozovatele (správce údajů)

Zapnutím logu zpracováváte osobní údaje ve smyslu GDPR, pokud dotazy nebo odpovědi mohou obsahovat identifikující informace (jméno v otázce, zdravotní stav, adresa, „jsem zaměstnanec XY“ atd.). I při anonymním session_id zůstává obsah textu potenciálně osobní. Níže jsou provozní povinnosti – nejde o právní poradenství; v doubt consultujte DPO nebo právníka.

7.1 Právní základ a účel

  • Účel zpracování – definujte písemně: např. „zlepšování obsahu exponátu, statistika dotazů návštěvníků, kontrola kvality odpovědí AI“.
  • Právní základ – typicky oprávněný zájem správce (čl. 6 odst. 1 písm. f) GDPR) po vyvážení s právy subjektů, nebo souhlas tam, kde zákon vyžaduje výslovný souhlas (např. některé školní projekty). U veřejného kiosku v EU zvažte informační povinnost spíše než tichý souhlas.
  • Minimalizace – log zapínejte jen pokud data skutečně využijete; v citlivých provozech (zdravotnictví, děti) zvažte agregaci bez ukládání plného textu.

7.2 Informační povinnost vůči návštěvníkům

Provozovatel musí návštěvníky informovat před nebo v okamžiku zpracování (čl. 13 GDPR). Doporučená místa:

  • informační tabule u kiosku (krátký text + QR na úplné zásady);
  • webové zásady ochrany osobních údajů provozovatele (muzea, města, firmy);
  • volitelně krátká věta v uvítacím textu exponátu (admin → Exponát), pokud to neodvádí pozornost od obsahu.

Minimální obsah informace (přizpůsobte identitě správce):

  • kdo je správce (název, kontakt);
  • že hlas je převáděn na text a odesílán poskytovateli AI (Google / OpenAI) a že text dotazu a odpovědi může být ukládán do databáze provozovatele;
  • účel (analýza provozu exponátu);
  • doba uchování (např. 90 dní);
  • práva subjektu (přístup, výmaz, námitka) a kontakt pro uplatnění;
  • odkaz na zásady cookies / mikrofonu v prohlížeči, pokud relevantní.

Viz také sekci 8 – texty připravené pro návštěvníky.

7.3 Doba uchování a mazání

  • Stanovte lhůtu retence (např. 30–180 dní podle provozu) a dodržujte ji.
  • Aplikace ji automaticky nemaže – plánujte cron / ruční SQL, např.: DELETE FROM exhibit_chat_log WHERE created_at < DATE_SUB(NOW(), INTERVAL 90 DAY);
  • Při ukončení provozu kiosku nebo změně účelu data vymažte nebo anonymizujte.

7.4 Zabezpečení a přístup

  • Přístup k admin-chat-log.php a MySQL jen pro oprávněné osoby (role, heslo admina, 2FA kde lze).
  • MySQL port neexponovat na internet – viz zabezpečení kiosku a sítě.
  • Zálohy databáze šifrovat; export logu neposílat e-mailem nešifrovaně.
  • Log není součástí veřejného check ani API odpovědi kiosku.

7.5 Zpracovatelé (subdodavatelé)

Samotný zápis do MySQL dělá váš server. Před zápisem ale text prochází k Google Gemini nebo OpenAI (cloud mimo vaši DB). Ve smlouvách a zásadách uveďte tyto zpracovatele; ověřte DPA / standardní smluvní doložky a region zpracování (EU / USA).

7.6 DPIA a zvláštní kategorie

  • U rozsáhlého monitoringu veřejnosti nebo citlivých prostor může být nutné posouzení vlivu (DPIA).
  • Neukládejte úmyslně zvláštní kategorie údajů (zdraví, biometrie, politika, náboženství…); filtry AI a profil Mládež / Muzeum snižují riziko, ale neodstraňují text z logu.

7.7 Práva subjektů údajů

Pokud se návštěvník domnívá, že je v logu jeho věta, musíte umět:

  • přístup – vyhledat podle data / obsahu textu (nemáte e-mail uživatele);
  • výmaz – smazat konkrétní řádky nebo celou relaci podle session_id, pokud ji dohledáte;
  • námitku – u zájmu jako právního základu posoudit podle čl. 21 GDPR;
  • odpověď do 1 měsíce (s možným prodloužením dle zákona).

Bez identifikátoru osoby může být výkon práv obtížný – proto je důležitá informační povinnost a krátká retence.

8. Informace pro návštěvníky (uživatele kiosku)

Návštěvník by měl rozumět, že exponát není anonymní hračka, ale služba s mikrofonem a cloudovou AI. Níže je vzorový text pro tabuli nebo web (upravte podle správce):

Vzor Informace u kiosku

Hlasový průvodce používá mikrofon a umělou inteligenci.
Vaši otázku převede na text a odešle poskytovateli AI (Google / OpenAI),
aby mohl odpovědět hlasem. Text dotazu a odpovědi může provozovatel
uchovávat v databázi nejdéle [90] dní za účelem zlepšování provozu exponátu.
Neukládáme vaše jméno ani kontakt. Podrobnosti: [odkaz na zásady ochrany osobních údajů].
Kontakt správce: [e-mail / adresa].

Co by měl návštěvník vědět prakticky:

  • Mikrofon – funguje jen po klepnutí na start a v prohlížeči s HTTPS; řeč se neukládá jako audio v logu provozovatele (může ji zpracovat prohlížeč / STT služba).
  • Co neříkat – vyhněte se sdělování citlivých osobních údajů nahlas, pokud to není nutné.
  • Děti – doporučte doprovod dospělé osoby; ve školách koordinujte s ředitelem a zákonným zástupcem.
  • Práva – návštěvník může požádat správce o informace nebo výmaz; uveďte kontakt na recepci / e-mail.

9. Kontrolní seznam před zapnutím logu

#KrokSplněno
1 MySQL funguje, tabulka exhibit_chat_log vytvořena Admin → Log konverzací
2 Právní základ a účel zpracování schváleny interně Dokumentace správce
3 Zásady ochrany osobních údajů doplněny o hlasový kiosk a log Web / PDF provozovatele
4 Informační tabule nebo text u exponátu Fyzický provoz
5 Retence a mazání starých řádků nastaveny Cron / provozní postup
6 Přístup k adminu a DB omezen; HTTPS na kiosku Zabezpečení provozu
7 Testovací dotaz na kiosku → záznam v admin-chat-log.php Ověření end-to-end

Související: Zabezpečení – shrnutí GDPR u logu, znalostní báze (jiný modul MySQL), administrace.