Radim: AI kolega ve Slacku, který zná firemní dokumentaci i živá data

Jak jsme v n8n postavili interního AI agenta, kterému kdokoli ve firmě napíše zprávu ve Slacku – a on odpoví z interní knowledge base a z produkční databáze. Celé na EU infrastruktuře, za jednotky korun na dotaz.
Proč jsme to stavěli
Každá firma má dvě studny znalostí, ze kterých se špatně pije. První je dokumentace — procesy, postupy, historie rozhodnutí, roztroušené po wiki a ve vláknech Slacku. Druhá jsou provozní data — kdo je jaký klient, v jakém stavu je smlouva, kolik přišlo plateb. K první se člověk musí prohledat, ke druhé potřebuje někoho, kdo umí SQL.
V praxi to znamená, že obchodník, účetní nebo support píše do vývojářského kanálu: „Můžete mi dohledat…?“ A vývojář přeruší práci, napíše SELECT, zkopíruje výsledek. Desetkrát týdně.
Radim tohle řeší. Je to Slack bot – kolega, kterému napíšete přímou zprávu nebo ho označíte v kanálu, položíte otázku česky a on:
- prohledá interní dokumentaci (RAG nad vektorovou databází),
- dotáže se produkční databáze (přirozeným jazykem – SQL si vygeneruje sám),
- obojí zkombinuje a odpoví ve vlákně, se zdroji a odkazy do administrace.
Typické dotazy z reálného provozu: „Jak funguje proces vyúčtování služeb?“ · „Najdi majitele s tímhle e-mailem a vypiš jeho smlouvy.“ · „Kolik plateb odešlo minulý týden a v jaké výši?“ · „Tři byty s nejvyšší reálnou marží za poslední 3 měsíce.“ Na poslední jmenovaný si agent sám navrhne agregační SQL dotaz a vrátí spočítaný výsledek – včetně poznámky, co čísla zkresluje.
Architektura v kostce
Celé to běží na self-hosted n8n instanci jako soustava workflow, které si mezi sebou předávají práci přes webhooky. Slack App umí posílat eventy jen na jednu URL – proto všechno teče do jednoho routeru, který event vyhodnotí a předá agentovi.

Klíčové rozhodnutí: nástroje agenta jsou samostatné n8n workflow („skilly“), které agent volá jako sub-workflow. Díky tomu jsou znovupoužitelné – stejný databázový skill může zítra volat jiný bot nebo automatizace, aniž by se cokoli duplikovalo.
Router: jeden vstup, tři druhy kontextu
Router má na první pohled nudnou, ale v praxi nejzrádnější práci: rozhodnout, na co vůbec reagovat a co dát agentovi jako kontext.

Dvě lekce, které nás tahle vrstva naučila:
- Bot si nesmí odpovídat sám sobě. Slack po odpovědi bota pošle event ’message_changed’, který nemá na první úrovni žádné ’bot_id’ — naivní filtr ho pustí dál a bot se roztočí v nekonečné konverzaci sám se sebou. Filtr proto kontroluje i zanořené struktury eventu.
- Kontext je měna. Původně jsme do DM přibalovali celou denní historii. Výsledek: dražší dotazy a agent, kterého mátly staré neúspěšné pokusy. Teď DM mimo vlákno startuje čistě – a kdo chce navázat, píše do vlákna. Uživatele jsme to naučili jednou větou v oznámení.
Mozek: L2 agent a jeho pravidla
Jádro je jeden AI Agent node v n8n s pečlivě laděným system promptem. Primární model je Gemini 3.5 Flash na EU regionu – rychlý, výborný ve vícekrokovém volání nástrojů a cenově rozumný. Má ale jednu vadu na kráse: v našem provozu přes gateway opakovaně padá na kapacitě (429 „Resource exhausted“ z Vertexu). Proto za ním v záloze stojí GPT-5.6 Terra na Azure — pomalejší, ale na úplně jiné infrastruktuře, takže nepadá spolu s ním (víc v kapitole o spolehlivosti). Agent smí iterovat (zavolat nástroj, přečíst výsledek, zavolat další), ale v mantinelech, které vyrostly z reálných průšvihů:
- Výpočty dělá databáze, ne model. Součty, průměry, marže a top-N si agent musí vyžádat jako hotovou SQL agregaci. LLM aritmetika nad vypsanými řádky je loterie – tohle pravidlo ji úplně obchází.
- Limity volání (databáze max. 6×, dokumentace max. 10× na odpověď) + strop iterací. Bez nich se agent na těžké otázce dokáže „zakousnout“ a bádat 20 dotazy – zažili jsme.
- Plánuj dopředu, volej dávkově. Místo ping-pongu jeden promyšlený plán a dotazy v dávkách.
- Zákaz odpovědi plánem. Agent nesmí napsat „podívám se a dám vědět“ konverzace končí jeho odpovědí, takže sliby nemá jak splnit. Buď zavolá nástroje hned, nebo přizná, že neví.
- Entity jako odkazy. Každé ID (smlouva, byt, klient…) v odpovědi je klikatelný odkaz do administrace – a vždy na produkci, nikdy vymyšlená URL.
Retry Gate: mezi agentem a Slackem stojí malý kontrolní uzel. Hlídá, jestli agent nevrátil prázdný výstup, surový JSON nebo „plán místo výsledku“ a v takovém případě ho automaticky spustí znovu (max. 2×). Až pak jde fallback hláška. Uživatel tak nikdy nedostane ticho ani technický výpis.
Nástroj 1: knowledge_base (RAG)
Dokumentační skill je klasický RAG: dotaz se převede na embedding, Qdrant vrátí nejrelevantnější výňatky z dokumentace včetně zdroje, agent z nich staví odpověď. Zajímavější je, odkud se data berou — knowledge base se plní ze čtyř stran a synchronizuje automaticky:

U projektové dokumentace je klíčový jeden detail: Claude Code skill ji píše a udržuje ve dvou verzích — ’user_guide’ a ’developer_guide’. Uživatelská verze popisuje, co funkce dělá očima člověka, který ji používá; vývojářská, jak je postavená uvnitř. Radim díky tomu umí přemostit obě strany: kolega se zeptá uživatelským jazykem („proč se klientovi nepropsala platba?“), Radim si v user_guide najde, o jakou funkci jde, v developer_guide, jak je technicky uchopená – a s tímhle porozuměním teprve formuluje dotaz do databáze. V praxi to nahrazuje vyhledávání přímo v kódu. To by bylo přesnější, ale řádově dražší časově i finančně – Radim není Claude Code a nemá být; dvouvrstvá dokumentace mu dává 90 % užitku za zlomek ceny.
Ten poslední zdroj je nenápadný, ale mocný: když ve Slacku proběhne hodnotná diskuse, stačí bota požádat a on z vlákna udělá strukturovaný markdown dokument a uloží ho do repozitáře. Znalost, která by umřela ve scrollbacku, se druhý den ráno stává součástí toho, co Radim „ví.“
Nástroj 2: database (přirozený jazyk → SQL → data)
Databázový skill je vlastní malá pipeline s vlastním, levnějším modelem. Hlavní agent mu pošle otázku česky a dostane zpět jen data — SQL zůstává uvnitř skillu.

Tři pojistky, bez kterých bychom to do produkce nepustili:
- Read-only replika zřízená přímo pro tento účel. Do produkční databáze se nesahá vůbec – skill fyzicky nemůže nic zapsat ani zpomalit produkci; v nejhorším případě zatíží jen vlastní repliku.
- SELECT-only sanitizace na úrovni kódu, ne promptu – regex kontrola před spuštěním čehokoli.
- Vynucený LIMIT. SELECT bez limitu jednou vrátil statisíce řádků a sestřelil celý n8n na paměti. Od té doby sanitizace doplní strop řádků každému dotazu, který ho nemá – agregace to nijak neomezuje, vrací pár řádků tak jako tak.
Spolehlivost: co se stane, když AI zrovna nefunguje
LLM API mají výpadky. Ne „jestli“, ale „kdy.“ Vrstvy obrany od nejrychlejší po poslední záchranu:

Fuckup, který stojí za přiznání: mysleli jsme si, že fallback máme vyřešený dávno – v gateway ležela nakonfigurovaná fallback politika a my žili v klidu. Pak přišel den, kdy Gemini padalo celé dopoledne, uživatelé dostávali omluvné hlášky… a v lozích ani jeden pokus o záložní model. Dvě chyby najednou: (1) fallback politika se neaplikuje sama od sebe jen tím, že existuje a je připnutá na API klíč – požadavek ji musí explicitně volat jako model (’policy/nazev-policy’); naše workflow celou dobu volalo Gemini napřímo, takže politika jen dekorovala nastavení. (2) Původní záloha byl jiný Gemini model na téže Vertex infrastruktuře — takže i kdyby se politika aplikovala, padala by spolu s primárním. Ponaučení: fallback stavějte přes různé poskytovatele (u nás Vertex → Azure) a hlavně si ho vyzkoušejte proti reálnému výpadku — nakonfigurovaný ≠ funkční.
GDPR a EU: proč tomu můžeme svěřit osobní údaje
Tohle je pro firemní nasazení možná nejdůležitější kapitola. Radim pracuje s reálnými jmény, e-maily a smlouvami – takže celý AI stack musel splnit tři podmínky:
- Výhradně EU regiony. Veškerá inference jde přes AI gateway (Requesty.ai), která routuje na Vertex AI v EU regionech a Azure OpenAI ve Švédsku. API klíč má navíc politiku, která ne-EU modely vůbec nepovolí – omylem to obejít nejde.
- Zero Data Retention – na datech se nic neučí. Dotazy slouží jen k vygenerování odpovědi, poskytovatelé je neukládají pro trénink.
- Data nikam „neodtékají“. Databáze je vlastní replika, vektorová DB vlastní instance, dokumentace vlastní Git. Ven jde jen samotný prompt na EU inference endpoint.
Díky tomu platí věta, kterou jsme napsali do interního oznámení: na rozdíl od veřejných AI chatů mu můžete poslat osobní údaje klienta – nic neopouští EU a nikdo se na tom neučí.
Co to stojí
Čísla z reálného provozu (přes AI gateway, která účtuje po jednotlivých voláních):
| Typ dotazu | Cena | Doba odpovědi |
|---|---|---|
| Jednoduchý (1–2 volání nástrojů) | ~1–1,5 Kč | do 1 minuty |
| Střední (kombinace dokumentace + DB) | ~2–3,5 Kč | 1–2 minuty |
| Složitá datová analýza | ~4–6 Kč | 2–4 minuty |
| Samotné vygenerování SQL (uvnitř skillu) | ~0,05–0,10 Kč | sekundy |
Dvě věci, které cenu drží dole: prompt caching (schéma databáze má ~45 tisíc tokenů – na Azure se cachuje za desetinu ceny, takže se neplatí pořád dokola) a levný specializovaný model na SQL — generování SQL nepotřebuje vlajkovou loď, stačí mini model, který to dělá spolehlivě a skoro zadarmo. Měsíční útrata celého bota je při současném provozu nižší než hodina práce vývojáře – a klíč má nastavený tvrdý měsíční strop, takže nepříjemné překvapení nehrozí.
Lekce z praxe
- Mantinely > důvěra. Limity volání, stropy iterací, vynucený LIMIT v SQL, časové pojistky. Všechna tahle pravidla vznikla až po incidentu – agent bez mantinelů si je najde za vás.
- Prompt je živý produkt. Ladili jsme ho po každé várce reálných konverzací: stručnost, zákaz výplňových frází, povinné odkazy na entity. Malé formulační změny mají překvapivě velký dopad.
- Levnější model ≠ horší výsledek – ale jen na správném místě. Mini model je skvělý na izolované generování SQL a propadl na orchestraci celého agenta. Testujte na svých úlohách, benchmarky nestačí.
- Nejlepší optimalizace je znalost. Když agent tápe 20 dotazy, není to chyba modelu – chybí mu doménový dokument. Každý dobrý dokument v knowledge base šetří peníze i minuty na všech budoucích dotazech.
Kam to míří dál
Jen ve zkratce, protože tohle je kapitola, která se teprve píše:
- Sentry tool — aby si agent k nahlášené chybě sám dohledal stacktrace a četnost výskytu.
- Jira tool — zakládání ticketů a sledování jejich stavu přímo z konverzace („založ na to úkol“ / „v jakém stavu je ten včerejší bug?“).
- Automatická triáž chyb — spojení obojího: kolega nahlásí chybu ve Slacku, agent dohledá kontext v Sentry, datech i dokumentaci a založí kompletní, podložený ticket. Z „nahlásil jsem to“ se stane „je to založené, s podklady.“
Závěr
Nejcennější na celém projektu není žádná jednotlivá technologie – všechno jsou to dostupné stavební kameny. Cenná je kombinace: jeden vstupní bod, kde lidé už stejně jsou (Slack), dva druhy znalostí pod jednou střechou (dokumentace + živá data) a provozní disciplína (EU-only, pojistky, fallbacky, logy), díky které se tomu dá věřit.
A možná ještě jedna věc: Radim má jméno, tvář a tyká si s lidmi. Zní to jako detail, ale adopce nástroje, kterému píšete jako kolegovi, je úplně jiná liga než adopce „formuláře na dotazy.“ Lidé se ho prostě ptají.