Lihoviny MAS

Architektura

Multiagentní systém pro konkurenční zpravodajství na trhu lihovin. Šest agentů běží každý ve vlastním kontejneru, nesdílí paměť ani nevolá funkce jiných agentů a mluví spolu jen zprávami přes Postgres. Nálezy zapisují na sdílenou tabuli ve stejné databázi.

Že spolu agenti opravdu mluví, ukazuje živě Log komunikace: najdete v něm každé Zadání, Odpověď, Dotaz i Selhání s odesílatelem, příjemcem a časem.

Diagram komunikace

Komunikace agentů Řídicí agent posílá přes sběrnici zpráv Zadání čtyřem sběrným agentům a analytickému agentovi. Sběrní agenti odpovídají Odpovědí nebo Selháním. Analytický agent posílá Dotazy, na které mu řídicí agent odpoví, a nakonec Odpověď s hotovým Briefem nebo Selhání. Sběrní agenti zapisují snímky a nálezy na sdílenou tabuli, analytický agent z ní čte nálezy a zapisuje na ni Brief, web z ní čte. Řídicí agent ridici Planning · rozvrh 6:00 a po 7:00 Sběrnice zpráv · Postgres LISTEN/NOTIFY Zadání Odpověď, Selhání Zadání, Odpověď Dotaz, Odpověď, Selhání Sběrní agenti · Collection a Processing Sortimentní agent sortimentni KIQ 1 · rohlik.cz Cenový agent cenovy KIQ 2 · akcniceny.cz Mediální agent medialni KIQ 3 · zboziaprodej.cz Regulatorní agent regulatorni KIQ 4 · psp.cz Analytický agent analyticky Analysis a Dissemination Brief v pondělí 7:00 zapisují snímky a nálezy čte nálezy, zapisuje Brief Sdílená tabule · Postgres snímky · produkty · nálezy · běhy · Briefy čte Web Brief, data podle KIQ, log Druhy zpráv (FIPA ACL) Zadání = REQUEST Odpověď = INFORM Dotaz = QUERY Selhání = FAILURE
Šipky ukazují, kdo komu posílá jaké zprávy. Každá zpráva přitom jde přes sběrnici: je to řádek v tabulce zpráv v Postgresu, žádný agent nevolá jiného přímo. Na úzké obrazovce jde diagram posunout do strany.

Šest agentů

Řídicí agent ridici

Fáze cyklu CI
Planning; uzavírá i zpětnou vazbu z Dotazů
Role
Drží KIT a čtyři KIQ a podle rozvrhu zahajuje běhy: každý den v 6:00 pošle Zadání sběrným agentům, v pondělí v 7:00 analytickému agentovi (pražský čas). Za agenta, který do 30 minut neodpoví, zapíše Selhání. Dotaz analytického agenta převede na nové Zadání pro sběrného agenta a výsledek mu vrátí.
Vnější zdroj
žádný, řídí se rozvrhem
LLM
jen převod textu Dotazu na Zadání

Sortimentní agent sortimentni

Fáze cyklu CI
Collection a Processing, KIQ 1 Sortiment
Role
Projde kategorii Lihoviny a její podkategorie, zařadí každý produkt do jedné z deseti kategorií a hlásí Novinky: produkty, které se u zdroje objevily poprvé od začátku sledování.
Vnější zdroj
rohlik.cz, data, která e-shop vkládá do stránky (__NEXT_DATA__)
LLM
jen nejasné kategorie a výrobce nové značky
Výstup na webu
Sortiment

Cenový agent cenovy

Fáze cyklu CI
Collection a Processing, KIQ 2 Akční ceny
Role
Sbírá akční ceny lihovin a RTD s řetězcem a obdobím platnosti, přepočítá je na cenu za litr a cenu za litr etanolu a páruje je s produkty ze sortimentu.
Vnější zdroj
akcniceny.cz, výpisy alkoholických nápojů (pauza 1 s podle crawl-delay)
LLM
jen záloha při párování akční ceny na produkt
Výstup na webu
Akční ceny

Mediální agent medialni

Fáze cyklu CI
Collection a Processing, KIQ 3 Komunikace
Role
Čte nové články oborového tisku. Články bez vztahu k lihovinám zahodí, u ostatních zapíše výrobce, značku, kanál, téma a shrnutí ve dvou větách. Jména osob neukládá.
Vnější zdroj
zboziaprodej.cz (Zboží&Prodej), posledních 30 článků přes WordPress REST API
LLM
relevance článku, výrobce, značka, kanál, téma a shrnutí
Výstup na webu
Komunikace

Regulatorní agent regulatorni

Fáze cyklu CI
Collection a Processing, KIQ 4 Regulace
Role
Hlídá nové sněmovní tisky o alkoholu (spotřební daň, reklama, prodej, značení) a ke každému odhadne dopad na výrobce lihovin a termín účinnosti. Místo jmen poslanců uvádí „skupina poslanců (strana)“.
Vnější zdroj
psp.cz, otevřená data Poslanecké sněmovny
LLM
až po filtru klíčových slov: relevance, dopad a termín účinnosti
Výstup na webu
Regulace

Analytický agent analyticky

Fáze cyklu CI
Analysis a Dissemination
Role
V pondělí čte nálezy všech čtyř KIQ ze sdílené tabule a píše Brief: Co se stalo podle KIQ, Netypické nálezy a Doporučení k portfoliu zadavatele, se 3–4 grafy a odkazy na zdroje. Když sběr některé KIQ selhal nebo vrátil prázdný snímek, pošle řídicímu agentovi Dotaz (nejvýš tři na běh, jedno kolo) a Brief napíše až po odpovědích. Selhání sběru, které doplnění nezaplnilo, v Briefu výslovně uvede.
Vnější zdroj
žádný; čte sdílenou tabuli a portfolio zadavatele
LLM
psaní Briefu
Výstup na webu
Brief

Kromě nich běží diagnostický agent Ozvěna (ozvena): na Zadání odpoví stejným obsahem, takže ověří sběrnici. V cyklu CI roli nemá.

Zprávy a sběrnice

Zpráva je řádek v tabulce zpráv: ID, ID konverzace, druh podle FIPA ACL, odesílatel, příjemce, obsah v JSON, čas odeslání a čas vyzvednutí. Odeslat zprávu znamená vložit řádek; databázový trigger pak pošle NOTIFY se jménem příjemce. Agent čeká na LISTEN, po probuzení si vyzvedne své nevyzvednuté zprávy a pro jistotu se na nové podívá i každých 30 sekund. Vyzvednutí zprávu hned označí, takže se doručí nejvýš jednou; když agent uprostřed práce spadne, pokryje to 30minutový limit řídicího agenta.

Tabulka zpráv je zároveň log komunikace: Log komunikace ukazuje živě každou zprávu, kdo ji komu poslal a kdy, seskupené po konverzacích, a Běhy výsledky jednotlivých Zadání.

Sdílená tabule

Vedle sběrnice je ve stejném Postgresu sdílená tabule (blackboard): data, která agenti zapisují a ostatní čtou. Zprávy na ně jen odkazují, třeba číslem snímku.

Snímky
Stav zdroje při jednom běhu jednoho sběrného agenta: zdroj, čas, odkazy na surové stažené stránky na disku a počet položek. Snímky se nepřepisují, takže z nich vzniká historie.
Produkty
Konkrétní balení lihoviny s normalizovaným klíčem (značka, název, objem, obsah alkoholu), výrobcem, kategorií a tím, kdy a kde ho agent viděl poprvé.
Nálezy
Nález je jedna zjištěná skutečnost s KIQ, typem (novinka, akční cena, článek, sněmovní tisk), odkazem na zdroj, obsahem a časem zjištění; může patřit k produktu a snímku. Není to zpráva: sběrný agent ho zapíše na tabuli a v Odpovědi pošle jen počet nových nálezů.
Běhy a Briefy
Řídicí agent si zapisuje běhy a výsledek každého Zadání, analytický agent hotové Briefy.

Sběrný agent zapíše snímek, produkty a nálezy v jedné transakci, takže tabule nikdy nedrží polovinu snímku. Analytický agent čte nálezy všech čtyř KIQ. Web čte tabuli i sběrnici přes databázovou roli, která smí jen číst.

Jak probíhá běh

  1. Každý den v 6:00 pražského času zahájí řídicí agent běh sběru a pošle Zadání všem čtyřem sběrným agentům, každému ve vlastní konverzaci.
  2. Sběrný agent stáhne svůj zdroj ohleduplně (pauza podle crawl-delay, při chybě tři pokusy s rostoucí pauzou), surové stránky uloží na disk a na tabuli zapíše snímek a nové nálezy. Řídicímu agentovi pošle Odpověď s přehledem, nebo Selhání s důvodem.
  3. Za agenta, který do 30 minut neodpoví, zapíše Selhání řídicí agent. Běh tak vždy skončí a stránka Běhy ukáže varování.
  4. V pondělí v 7:00 pošle řídicí agent Zadání analytickému agentovi i s přehledem posledního sběru, takže Brief ví, který zdroj selhal.
  5. Analytický agent zjistí, který sběr selhal. Za takovou KIQ pošle řídicímu agentovi Dotaz; ten zadá doplňující sběr a výsledek mu vrátí. Tady se cyklus CI uzavírá zpětnou vazbou a v logu je to v jedné konverzaci se Zadáním Briefu: Dotaz, Zadání z Dotazu a dvě Odpovědi.
  6. Analytický agent dopíše Brief, uloží ho na tabuli a řídicímu agentovi odpoví. Web Brief ukáže zadavateli.

Agenti jako samostatné služby

Všichni agenti používají jeden Docker image; každý běží ve vlastním kontejneru a služba v Docker Compose určuje jen příkaz lihoviny agent <jméno>. Výpadek jednoho agenta ostatní nezastaví. Vedle agentů běží Postgres (sběrnice i tabule), jednorázová služba, která před startem agentů aplikuje migrace schématu, a web (FastAPI se stránkami vykreslenými na serveru, bez JavaScriptu). Agenti volají Claude API přes oficiální SDK; model jde nastavit zvlášť pro každého agenta a API klíč je jen na serveru.

Proč Postgres, a ne RabbitMQ nebo framework jako CrewAI či LangGraph: je to jediná služba navíc, log komunikace je přímo tabulka zpráv a agenti zůstávají samostatné procesy (frameworky je spouštějí v jednom procesu). Cenou je jediný bod selhání: když Postgres neběží, nekomunikuje nikdo. Rozhodnutí popisuje ADR 0001 v repozitáři (docs/adr/0001-agenti-v-kontejnerech-postgres-jako-sbernice.md).