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

77 lines
4.1 KiB
Markdown

# 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 API**`newest_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. **RČ** 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í
```powershell
python U:\ordinaceprojekt\OrdinaceAgentEmail\recepty_agent.py
```