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
Š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__)
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)
Č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í
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 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.
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í.
Zadání REQUEST
Řídicí agent sběrnému nebo analytickému agentovi: co a kde má zjistit. Každé Zadání
z rozvrhu nebo ručního běhu zahajuje vlastní konverzaci, do které patří i odpověď;
u Briefu v ní zůstávají i Dotazy, Zadání z Dotazu a odpovědi na ně. Ručně ho může
poslat člen týmu (odesílatel clen-tymu), třeba při předvedení.
Odpověď INFORM
Výsledek Zadání nebo Dotazu ve stejné konverzaci. Sběrný agent v ní posílá jen přehled
{"snapshot_id", "new_findings", "item_count"}: který snímek zapsal, kolik
přibylo nových nálezů a kolik položek snímek má. Samotné nálezy jsou na sdílené tabuli,
ne ve zprávě.
Dotaz QUERY
Analytický agent řídicímu agentovi, když sběr některé KIQ selhal nebo vrátil prázdný
snímek: KIQ, co chybí a návrh doplňujícího sběru. Řídicí agent z něj udělá nové Zadání
(Zadání z Dotazu) pro sběrného agenta té KIQ a jeho výsledek vrátí jako Odpověď (nebo
Selhání). Nejvýš tři Dotazy a jedno kolo zpětné vazby na běh; doplnění musí skončit do
15 minut od Zadání Briefu, aby se Brief stihl dopsat do 30 minut.
Selhání FAILURE
Zadání se nepodařilo splnit, s důvodem: zdroj nebyl dostupný ani po třech pokusech, nebo
z něj agent nic nevyčetl. Když agent do 30 minut neodpoví vůbec, zapíše Selhání za něj
řídicí agent. Brief každou takovou mezeru výslovně uvede.
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
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.
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.
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í.
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.
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.
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).