Files
ordinaceprojekt/OrdinaceAgentEmail/NOTES.md
T
2026-06-12 15:32:22 +02:00

4.1 KiB

OrdinaceAgentEmail — agent na žádosti o recept

Hledá ve schránce ordinace@buzalkova.cz e-maily, kde pacient žádá o předepsání léku (recept), vytěžuje pacienta + požadované léky a pacienta ověřuje v kartotéce Medicusu.

Stav: testovací režim (read-only)

recepty_agent.py zatím jen načte NEWEST_N (= 5) nejnovějších mailů z Inboxu, klasifikuje je Claude modelem a vypíše report do konzole a _log_recepty.txt. Ve schránce nic nemění (žádné kategorie, přesuny, odpovědi), žádný state.json.

Tok

  1. Graph APInewest_inbox_messages(): N nejnovějších mailů z Inboxu, bez filtru na přílohy ($orderby receivedDateTime desc — bez filtru funguje, na rozdíl od kombinace s hasAttachments, viz EmailAgent).
  2. AI klasifikace + vytěžení (Claude claude-haiku-4-5) — pro každý mail JSON: je_zadost_o_recept, pacient (může se lišit od odesílatele — příbuzní píší za pacienta), rodne_cislo (přesně jak je v textu), datum_narozeni, leky[] (nazev + poznamka), poznamka, duvod.
  3. Ověření v Medicusu (MedicusLookup) — celá kartotéka se načte do paměti (KAR ~6300 pacientů + kontakty z KARKONTAKT: ~70 e-mailů, ~4150 telefonů; TYP: 1=pevná, 2=mobil, 3=e-mail). Párování v pořadí spolehlivosti:
    1. z textu mailu (Medicus ukládá RČ bez lomítka) — jednoznačné,
    2. e-mail odesílatele proti KARKONTAKT,
    3. telefon z textu mailu proti KARKONTAKT (jen číslice, bez +420 — telefonů je v kartotéce hodně, často rozhodne i duplicitní jména),
    4. jméno — bez diakritiky, bez ohledu na pořadí slov (Jaroslav Klíma = Klíma Jaroslav); při více kandidátech zúžení datem narození (z datum_narozeni nebo odvozeným z nesedícího RČ). Výstup: [SHODA RČ/E-MAIL/JMÉNO/JMÉNO+DATUM] s detaily pacienta (RČ, datum narození, pojišťovna, idpac, příznak vyřazení), nebo [NENALEZEN].
  4. Nejednoznačnost (více pacientů stejného jména, např. otec a syn)resolve_by_prescriptions(): načte nestornované recepty kandidátů z tabulky RECEPT (STORNO <> 'T', posledních RECEPT_MONTHS = 24 měsíců) a rozhodne podle shody požadovaných léků s historií:
    1. Deterministicky_drug_matches(): substring oběma směry („tadalafil" ~ „TADALAFIL ACCORD") + prefix prvních slov od 5 znaků („Concord" ~ „CONCOR"). Jediný kandidát s nejvyšším nenulovým skóre vyhrává → [SHODA JMÉNO+LÉKY V HISTORII].
    2. Claude fallback — když deterministika nerozhodne (nikdo/více se shodou), model dostane požadované léky + seznamy předepsaných léků kandidátů a rozhodne i přes generika/účinné látky → [SHODA JMÉNO+LÉKY+AI]. Když ani AI nerozhodne → [NEROZHODNUTO]
      • výpis kandidátů k ruční kontrole.
  5. Report + cena AI za běh (~0,04 Kč/mail).

Sdílená infrastruktura

  • EmailAgent/graph_mail.py — import přes sys.path (stejná app registrace, Mail.Read Application). Credentials natvrdo tam.
  • Knihovny/medicus_db.py — Firebird připojení k Medicusu (DSN podle názvu počítače, na Z230 → reporter:c:\medicus\medicus.fdb).
  • ANTHROPIC_API_KEY z Medevio/.env.

Známé limity / TODO

  • E-mailových kontaktů je v kartotéce málo (~70 z 6300 pacientů) — párování e-mailem zabere zřídka; telefonů je ~4150, proto se vytěžuje i telefon z textu mailu. Do budoucna by šlo e-mail odesílatele po ručním potvrzení do KARKONTAKT doplňovat.
  • Párování jménem vyžaduje přesnou shodu množiny slov — překlepy ve jméně nenajde (kandidát: fuzzy matching / nabídka podobných jmen).
  • Zatím bez označování mailů, bez summary e-mailu, bez odpovědi pacientovi — kandidáti na další krok (vzor: EmailAgent/faktury_agent.py).
  • Bez idempotence (žádný state) — testovací běhy čtou vždy posledních N mailů.

Spuštění

python U:\ordinaceprojekt\OrdinaceAgentEmail\recepty_agent.py