Technické riešenie

Postavené na overených technológiách

Contineo spája sémantické vyhľadávanie (RAG) nad vaším obsahom s jazykovým modelom, ktorý odpovedá výhradne z overených zdrojov — s citáciou a verziou.

Príklady na tejto stránke (sekcie, značky, dotazy) vychádzajú z generickej firmy. Contineo je doménovo univerzálne — „predpis“ je len jeden druh dokumentu a „jednotka“ len jeden druh organizácie. Konkrétne nasadenie do veľkej organizácie nájdete v prípadovej štúdii nižšie.

Späť na hlavnú stránku

Architektúra a dátový tok

Architektúra a dátový tok

Vstupné kanály → spracovanie (chunking + značkovanie) → MongoDB (jadro: hybridné vyhľadávanie) → AI adaptéry (embedding, rerank, generovanie) → rozhrania. Jadro je v cloude aj on-prem identické — $rankFusion beží rovnako v Atlase aj v self-hosted Community 8.2. Líšia sa len tri adaptéry, ktoré sa vyberajú konfiguráciou tenanta. AI dostane vždy len relevantné pasáže; dáta zostávajú vo vašej databáze. Súčasťou sú dva spätné cykly: kurácia (kontrola kvality) a eskalácia na ticket.

Kľúčové piliere

RAG + Hybrid Search

Hybridné vyhľadávanie $rankFusion (vektor 60 % + fulltext 40 %) je jadro systému a beží identicky v MongoDB Atlas aj v self-hosted Community 8.2. Odpoveď vzniká výhradne z nájdených pasáží.

Vymeniteľné AI adaptéry

Embedding, rerank a generovanie sú tri nezávislé adaptéry vyberané konfiguráciou tenanta, nie kódom. Cloud: Voyage a Claude. On-prem: Infinity alebo TEI a vLLM s modelom podľa vášho výberu (Qwen3, EuroLLM, Gemma).

Citácie a verzie

Každá odpoveď uvádza zdroj a verziu. Import novej verzie nestratí starú — cituje sa vždy platné znenie.

Multi-tenant a bezpečnosť

Hierarchia organizácií (centrála → regionálne → lokálne jednotky) ako samostatní tenanti. Verejný obsah vidia všetci; interný obsah len príslušníci danej jednotky. Audit pri každej zmene znalostí.

Vstupné kanály (obsah aj integrácie)

Jedna vrstva, ktorou tečie obsah: PDF dokumenty a predpisy, FAQ, weby (RSS), interné smernice, MCP konektory (Drive, SharePoint, Confluence…) aj e-mail (IMAP) — zjednotené do jedného indexu. Pripojený zdroj identity (napr. sportnet.online) tu poskytuje identitu, nie obsah.

Helpdesk a e-mail

Sledovanie e-mailových schránok, ticketing a predpripravené odpovede s eskaláciou z vyhľadávania.

Kontrola kvality a kurácia

Nejde o strojové učenie modelu, ale o ľudskú kuráciu: správca ohodnotí a schváli odpoveď, tá sa uloží ako nový pár (qa_pair) a embeduje späť. Nový pár nikdy potichu neprepíše schválený predpis.

Kľúčové dátové toky

01

Odpovedanie (RAG + Hybrid)

Dotaz sa klasifikuje (fulltext / vector / hybrid). $rankFusion zlúči $vectorSearch a $search — identicky v oboch režimoch. Rerank a generovanie potom obslúži adaptér podľa profilu tenanta: v cloude $rerank v databáze a Claude API, on-prem Infinity a vLLM. Odpoveď ide streamingom s citáciou zdroja.

02

Eskalácia na ticket

Neúspech = nízke skóre podobnosti alebo negatívne hodnotenie. Po 3 neúspechoch na tú istú tému bot ponúkne vytvorenie ticketu aj s celým kontextom konverzácie.

03

Kontrola kvality a kurácia

Nie strojové učenie, ale ľudská kurácia: schválené odpovede z ContineoLearning aj z upravených e-mailových odpovedí sa uložia ako qa_pair a embedujú späť do znalostí. Nový pár nikdy potichu neprepíše schválený predpis.

Hlavné kolekcie

Návrh oddeľuje znalosti (jadro RAG) od konverzácií a ticketov. Verzovanie noriem zaručuje, že import novej verzie nestratí staršiu.

document_chunks — jadro RAG

{
  _id, documentId, versionId,
  sourceType: "pdf",            // pdf | faq | rss | qa | email

  // tagging (used for filtering at search time)
  sectionKey: "smernice",
  companyCode: "ACME-BA",       // "ACME" = applies company-wide
  scope: "company",         // global | company | region
  language: "sk",

  // content
  articleRef: "čl. 4 ods. 2",
  heading: "Práca z domu (home office)",
  text: "Zamestnanec má nárok na home office...",

  // vector + identita vektorového priestoru
  embedding: [0.0123, -0.044, ...],   // 1024 dims
  embeddingModel: "voyage-4",         // POVINNÉ — ktorý model vektor vyrobil
  embeddingDim: 1024,                 // kontrola pri zápise aj čítaní
  embeddingProvider: "atlas-auto",    // atlas-auto | infinity | tei
  embeddedAt: ISODate(),              // pre plánovanie re-embedu

  isActive: true,               // false = archived version
  effectiveFrom, effectiveTo
}

tickets

{
  ticketNumber: "CNT-2026-000412",
  source: "bot",                // bot | email
  status: "open",               // lifecycle below
  priority: "normal",
  sectionKey: "hr",
  companyCode: "ACME-BA",
  requester: { email, name, userRef },
  subject, conversationId,      // full context if from bot
  assignedTo, slaDueAt,
  resolution: { answeredBy, qaPairId, closedAt },
  tags: []
}

Hybridný vyhľadávací dotaz ($rankFusion)

Otázka z prostredia jednotky „ACME-BA”, sekcia interné smernice, len platná verzia. $rankFusion kombinuje vektorové a fulltextové vyhľadávanie — tento dotaz je identický v cloude aj on-prem. Rerank je samostatný krok mimo tohto dotazu: v cloude ako $rerank stage, on-prem cez Infinity nad výsledkom.

db.document_chunks.aggregate([
  { $rankFusion: {
      input: {
        pipelines: {
          vector: [{ $vectorSearch: {
            index: "rag_vector_index",   // index viazaný na embeddingModel
            path: "embedding",
            queryVector: queryEmbedding, // z adaptéra podľa profilu
            numCandidates: 200, limit: 20,
            filter: { sectionKey: { $eq: "smernice" },
                      companyCode: { $in: ["ACME-BA","ACME"] },
                      isActive: { $eq: true } }
          }}],
          fulltext: [{ $search: {
            index: "rag_text_index",
            text: { query: queryText, path: "text" }
          }}]
        }
      },
      combination: { weights: { vector: 0.6, fulltext: 0.4 } }
  }},
  { $limit: 20 },
  { $project: {
      text: 1, heading: 1, articleRef: 1,
      score: { $meta: "rankFusionScore" }  // -> signál pre eskaláciu
  }}
])

// Tento dotaz je identický v cloude aj on-prem.
// Rerank je samostatný krok MIMO neho, podľa profilu tenanta:
//   cloud   -> { $rerank: { index: "rag_rerank_index",
//                           query: queryText, limit: 8 } }
//              sa pripojí ako ďalší stage (MongoDB Atlas 8.3+)
//   on-prem -> POST /rerank na Infinity/TEI nad výsledkom vyššie
//
// Počet kandidátov na vstupe rerankera drž rovnaký (20),
// aby boli oba režimy porovnateľné na eval sade D9.

Vymeniteľné adaptéry a profil tenanta

Embedding, rerank aj generovanie sú tri nezávislé adaptéry. Ktorý sa použije, určuje záznam v kolekcii tenant_profiles — nie kód. Jedna inštalácia tak obslúži cloudového aj on-prem zákazníka súčasne, s rovnakým jadrom vyhľadávania.

tenant_profiles — voľba adaptérov

{
  companyCode: "ACME",          // kľúč, zhodný s chunkami
  tier: "T1",                   // T1 shared | T2 enclave | T3 air-gap
  dataResidency: "eu",          // eu | on-prem | air-gap

  providers: {
    embedding: {
      kind: "atlas-auto",       // atlas-auto | infinity | tei
      model: "voyage-4", dim: 1024,
      index: "rag_vector_index"
    },
    rerank: {
      kind: "atlas-stage",      // atlas-stage | infinity | tei | none
      model: "rerank-2", topK: 8
    },
    generation: {
      kind: "anthropic",        // anthropic | openai
      model: "claude-sonnet-5",
      citations: true, promptCaching: true
    }
  }
}

// Ten istý tenant v uzavretom režime — mení sa len profil:
//   embedding:  { kind: "infinity", model: "voyage-4-nano", dim: 1024 }
//   rerank:     { kind: "infinity", model: "BAAI/bge-reranker-v2-m3" }
//   generation: { kind: "openai", url: "http://vllm:8000/v1",
//                 model: "Qwen3-8B", citations: false }

Čo sa medzi režimami líši

Jadro je identické, ale úplná funkčná parita neexistuje. Toto sú rozdiely, s ktorými treba počítať pri výbere režimu.

SchopnosťCloudOn-prem
$rankFusion hybridné vyhľadávanieánoáno — identické
Automatický embedding v databázeánovolá Voyage API — pre air-gap nepoužiteľné
$rerank priamo v pipelineánonie — rerank v aplikačnej vrstve
Overiteľné citácie (Citations API)ánonie — citácie sa žiadajú promptom
Prompt cachingánoprefix caching vo vLLM, iná sémantika
Dáta neopustia perimeternieáno

Vektory nie sú prenositeľné medzi modelmi — zmena embedding modelu znamená úplný re-embed korpusu. Rozhodnutie a jeho dôsledky sú zdokumentované v ADR-001.

Značkovanie obsahu

Každý úryvok odpovedá na tri otázky — o čom je (sekcia), pre koho platí (organizácia/rozsah) a z ktorej verzie. Hodnoty sa vyberajú z číselníka, nie ako voľný text.

Číselník sekcií

vseobecneVšeobecné informácie
smerniceInterné smernice
hrHR a personalistika
ekonomickeEkonomika a financie
it_aplikacieIT a aplikácie
gdprGDPR a právne

Rozsah platnosti

  • scope: global + centrála (napr. ACME) → platí pre celú firmu
  • scope: company + kód jednotky → platí len pre danú jednotku
  • scope: region → platí pre regionálnu úroveň

Príklady označkovaných úryvkov

// company-wide policy (applies to all units)
{ sourceType: "pdf", sectionKey: "smernice",
  companyCode: "ACME", scope: "global",
  articleRef: "čl. 4 ods. 2", isActive: true }

// document specific to one unit
{ sourceType: "pdf", sectionKey: "hr",
  companyCode: "ACME-BA", scope: "company",
  articleRef: "čl. 8", isActive: true }

// IT FAQ for an internal app (FAQ, not a policy)
{ sourceType: "faq", sectionKey: "it_aplikacie",
  companyCode: "ACME", scope: "global",
  articleRef: null, isActive: true }

Pravidlá pre konzistentné značkovanie

  • sectionKey a companyCode vždy z číselníka, nikdy voľný text.
  • Celofiremné predpisy: centrála + scope global — nekopírovať pre každú jednotku.
  • articleRef vypĺňať pri predpisoch — používa sa v citácii odpovede.
  • Pri novej verzii staré chunky nemazať — isActive: false + effectiveTo.

Životný cyklus ticketu

Ticket vznikne z bota alebo z e-mailu a prechádza stavmi:

newprišiel, prebieha auto-triage (sekcia, jednotka, návrh odpovede)
openpriradený správcovi, pracuje sa naň
waitingčaká sa na doplnenie od žiadateľa (SLA pozastavené)
resolvedodoslaná odpoveď; úprava pri odoslaní = nový qa_pair
closeduzavretý; reopen vráti do open

Integrácie

E-mail (IMAP)

Dve sledované schránky (tickety + štandardné otázky); worker ich smeruje do ticketu alebo do učiaceho toku.

Zdroj identity a CRM (napr. sportnet.online)

Prihlásenie cez OAuth a CRM ako zdroj pravdy o osobách a organizačných jednotkách: používatelia sa zakladajú automaticky, roly a skupiny podľa príslušnosti k jednotke/tímu (cez mapovaciu tabuľku alebo ručne). Contineo má vlastnú databázu, nezapisuje späť. V športovom nasadení je týmto zdrojom sportnet.online (pozri prípadovú štúdiu).

RSS / web

Pre všeobecné informácie worker periodicky ťahá RSS; nové položky → documents → chunky.

MCP konektory

Pripojiteľné zdroje cez MCP — Google Drive, SharePoint, Confluence, Notion, Slack a ďalšie. Obsah sa indexuje rovnako ako ostatné zdroje.

Bezpečnosť a prevádzka

  • Prístup podľa príslušnosti k organizácii/jednotke a skupín (automaticky z pripojeného zdroja identity, napr. sportnet.online v športe); kto smie nahrávať obsah, sa povoľuje ručne. Audit pri každej zmene znalostí.
  • Prihlásenie cez SSO: Microsoft Entra ID, Google Workspace (v športe aj sportnet.online); verejný obsah aj bez prihlásenia.
  • Citácia verzie v každej odpovedi a archivácia starých verzií predpisov.
  • Monitoring kvality: skóre, podiel eskalácií a hodnotenia ako spätná väzba.
  • Multi-tenant hierarchia (centrála → regionálne → lokálne jednotky): verejný obsah vidia všetci, interný obsah je oddelený per organizácia.
  • Súkromie dát: obsah ostáva vo vašej databáze a úložisku; AI odpovedá výhradne z vášho obsahu (RAG), verejná spotrebiteľská AI sa nepoužíva.
  • Voľba prevádzkového režimu na úrovni tenanta: cloud (EU rezidencia, zero-retention zmluva) alebo plne on-prem — obsah ani dotazy neopustia vašu infraštruktúru. Jedna inštalácia obslúži oba typy zákazníkov súčasne.

Identita a riadenie prístupu

Prihlásenie cez existujúce SSO; prístupové právo je povinný filter odvodený zo session a aplikovaný na obe vetvy hybridného vyhľadávania ($vectorSearch aj $search).

Poskytovatelia identity (NextAuth) → jedna kanonická session

OAuth / OIDCprimárny login; v športovom nasadení napr. sportnet.online + zdroj členstiev a rolí
Microsoft Entra IDSSO pre firemné účty zamestnancov
Google WorkspaceSSO (alternatíva)
CRM / API zdroja identityzdroj pravdy o osobách a organizačných jednotkách; mapovanie na companyCode, roly a skupiny
Vlastná databázaúčty mimo SSO (credentials)

Princípy bezpečnosti

  • Server-side only — filter sa skladá zo session, nikdy z parametrov klienta.
  • Default-deny — čo nie je výslovne povolené, sa nevráti; bez identity len verejný obsah.
  • Filter pred LLM — model vidí len povolené chunky; nedá sa obísť promptom (platí aj pre citácie).
  • Auto-provisioning — používatelia, roly a skupiny sa zakladajú a synchronizujú z CRM (login + webhook).

Dva režimy nasadenia

Verejný widget

anonymný; vidí len verejný obsah naprieč celou hierarchiou.

Interný portál (SSO)

prihlásený; vidí verejný + interný obsah jednotiek, ku ktorým má vzťah.

Prípadová štúdia

Nasadenie vo veľkej organizácii — športový zväz (SFZ)

Contineo je doménovo univerzálne. Takto vyzerá jedno reálne nasadenie do veľkej organizácie — Slovenského futbalového zväzu a jeho podriadených zväzov.

  • Tenant hierarchia: SFZ → regionálne → oblastné zväzy ako samostatné organizácie.
  • Obsah: súťažné a prestupové poriadky, rozpisy súťaží, smernice, IT FAQ (aplikácia ISSF).
  • Identita: prihlásenie a CRM cez sportnet.online (OAuth) — používatelia a roly podľa príslušnosti k zväzu/klubu.
  • Príklad otázky: „Môže hráč nastúpiť v dvoch stretnutiach za jeden deň?“ → odpoveď s citáciou § a verzie.

Technologický stack

MongoDB — jadro: $rankFusion (Atlas EU alebo Community 8.2)Cloud · Voyage AI voyage-4 — Automated EmbeddingCloud · Voyage AI rerank-2.5 — $rerank v databázeCloud · Claude API — Citations, prompt cachingOn-prem · Infinity / TEI — embedding + rerankOn-prem · vLLM — Qwen3, EuroLLM, GemmaNext.js 14 (App Router) · Node.js workerIntegrácie: e-mail (IMAP), zdroj identity/CRM (napr. sportnet.online), MCP konektory