Technické řešení

Postaveno na ověřených technologiích

Contineo spojuje sémantické vyhledávání (RAG) nad vaším obsahem s jazykovým modelem, který odpovídá výhradně z ověřených zdrojů — s citací a verzí.

Příklady na této stránce (sekce, značky, dotazy) vycházejí z generické firmy. Contineo je doménově univerzální — „předpis“ je jen jeden druh dokumentu a „jednotka“ jen jeden druh organizace. Konkrétní nasazení do velké organizace najdete v případové studii níže.

Zpět na hlavní stránku

Architektura a datový tok

Architektura a datový tok

Vstupní kanály → zpracování (chunking + značkování) → MongoDB (jádro: hybridní vyhledávání) → AI adaptéry (embedding, rerank, generování) → rozhraní. Jádro je v cloudu i on-prem identické — $rankFusion běží stejně v Atlasu i v self-hosted Community 8.2. Liší se jen tři adaptéry, které se vybírají konfigurací tenanta. AI dostane vždy jen relevantní pasáže; data zůstávají ve vaší databázi. Součástí jsou dva zpětné cykly: kurace (kontrola kvality) a eskalace na ticket.

Klíčové pilíře

RAG + Hybrid Search

Hybridní vyhledávání $rankFusion (vektor 60 % + fulltext 40 %) je jádro systému a běží identicky v MongoDB Atlas i v self-hosted Community 8.2. Odpověď vzniká výhradně z nalezených pasáží.

Vyměnitelné AI adaptéry

Embedding, rerank a generování jsou tři nezávislé adaptéry vybírané konfigurací tenanta, ne kódem. Cloud: Voyage a Claude. On-prem: Infinity nebo TEI a vLLM s modelem podle vašeho výběru (Qwen3, EuroLLM, Gemma).

Citace a verze

Každá odpověď uvádí zdroj a verzi. Import nové verze neztratí starou — cituje se vždy platné znění.

Multi-tenant a bezpečnost

Hierarchie organizací (centrála → regionální → lokální jednotky) jako samostatní tenanti. Veřejný obsah vidí všichni; interní obsah jen příslušníci dané jednotky. Audit při každé změně znalostí.

Vstupní kanály (obsah i integrace)

Jedna vrstva, kterou teče obsah: PDF dokumenty a předpisy, FAQ, weby (RSS), interní směrnice, MCP konektory (Drive, SharePoint, Confluence…) i e-mail (IMAP) — sjednoceno do jednoho indexu. Připojený zdroj identity zde poskytuje identitu, ne obsah.

Helpdesk a e-mail

Sledování e-mailových schránek, ticketing a předpřipravené odpovědi s eskalací z vyhledávání.

Kontrola kvality a kurace

Nejde o strojové učení modelu, ale o lidskou kuraci: správce ohodnotí a schválí odpověď, ta se uloží jako nový pár (qa_pair) a naembeduje zpět. Nový pár nikdy potichu nepřepíše schválený předpis.

Klíčové datové toky

01

Odpovídání (RAG + Hybrid)

Dotaz se klasifikuje (fulltext / vector / hybrid). $rankFusion sloučí $vectorSearch a $search — identicky v obou režimech. Rerank a generování pak obslouží adaptér podle profilu tenanta: v cloudu $rerank v databázi a Claude API, on-prem Infinity a vLLM. Odpověď jde streamingem s citací zdroje.

02

Eskalace na ticket

Neúspěch = nízké skóre podobnosti nebo negativní hodnocení. Po 3 neúspěších na totéž téma bot nabídne vytvoření ticketu i s celým kontextem konverzace.

03

Kontrola kvality a kurace

Ne strojové učení, ale lidská kurace: schválené odpovědi z ContineoLearning i z upravených e-mailových odpovědí se uloží jako qa_pair a naembedují zpět do znalostí. Nový pár nikdy potichu nepřepíše schválený předpis.

Hlavní kolekce

Návrh odděluje znalosti (jádro RAG) od konverzací a ticketů. Verzování norem zaručuje, že import nové verze neztratí starší.

document_chunks — jádro 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í vyhledávací dotaz ($rankFusion)

Otázka z prostředí jednotky „ACME-PR”, sekce interní směrnice, jen platná verze. $rankFusion kombinuje vektorové a fulltextové vyhledávání — tento dotaz je identický v cloudu i on-prem. Rerank je samostatný krok mimo tento dotaz: v cloudu jako $rerank stage, on-prem přes Infinity nad výsledkem.

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.

Vyměnitelné adaptéry a profil tenanta

Embedding, rerank i generování jsou tři nezávislé adaptéry. Který se použije, určuje záznam v kolekci tenant_profiles — ne kód. Jedna instalace tak obslouží cloudového i on-prem zákazníka současně, se stejným jádrem vyhledávání.

tenant_profiles — volba adaptérů

{
  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 }

Co se mezi režimy liší

Jádro je identické, ale úplná funkční parita neexistuje. Toto jsou rozdíly, se kterými je třeba počítat při výběru režimu.

SchopnostCloudOn-prem
$rankFusion hybridní vyhledáváníanoano — identické
Automatický embedding v databázianovolá Voyage API — pro air-gap nepoužitelné
$rerank přímo v pipelineanone — rerank v aplikační vrstvě
Ověřitelné citace (Citations API)anone — citace se žádají promptem
Prompt cachinganoprefix caching ve vLLM, jiná sémantika
Data neopustí perimetrneano

Vektory nejsou přenositelné mezi modely — změna embedding modelu znamená úplný re-embed korpusu. Rozhodnutí a jeho důsledky jsou zdokumentovány v ADR-001.

Značkování obsahu

Každý úryvek odpovídá na tři otázky — o čem je (sekce), pro koho platí (organizace/rozsah) a z které verze. Hodnoty se vybírají z číselníku, ne jako volný text.

Číselník sekcí

vseobecneObecné informace
smerniceInterní směrnice
hrHR a personalistika
ekonomickeEkonomika a finance
it_aplikacieIT a aplikace
gdprGDPR a právní

Rozsah platnosti

  • scope: global + centrála (např. ACME) → platí pro celou firmu
  • scope: company + kód jednotky → platí jen pro danou jednotku
  • scope: region → platí pro regionální úroveň

Příklady označkovaných úryvků

// 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 }

Pravidla pro konzistentní značkování

  • sectionKey a companyCode vždy z číselníku, nikdy volný text.
  • Celofiremní předpisy: centrála + scope global — nekopírovat pro každou jednotku.
  • articleRef vyplňovat u předpisů — používá se v citaci odpovědi.
  • Při nové verzi staré chunky nemazat — isActive: false + effectiveTo.

Životní cyklus ticketu

Ticket vznikne z bota nebo z e-mailu a prochází stavy:

newpřišel, probíhá auto-triage (sekce, jednotka, návrh odpovědi)
openpřidělen správci, pracuje se na něm
waitingčeká se na doplnění od žadatele (SLA pozastavena)
resolvedodeslána odpověď; úprava při odeslání = nový qa_pair
closeduzavřen; reopen vrátí do open

Integrace

E-mail (IMAP)

Dvě sledované schránky (tickety + standardní dotazy); worker je směruje do ticketu nebo do učicího toku.

Zdroj identity a CRM

Přihlášení přes OAuth a CRM jako zdroj pravdy o osobách a organizačních jednotkách: uživatelé se zakládají automaticky, role a skupiny podle příslušnosti k jednotce/týmu (přes mapovací tabulku nebo ručně). Contineo má vlastní databázi, nezapisuje zpět. Ve sportovním nasazení je tímto zdrojem sportnet.online (viz případová studie).

RSS / web

Pro obecné informace worker periodicky stahuje RSS; nové položky → documents → chunky.

MCP konektory

Připojitelné zdroje přes MCP — Google Drive, SharePoint, Confluence, Notion, Slack a další. Obsah se indexuje stejně jako ostatní zdroje.

Bezpečnost a provoz

  • Přístup podle příslušnosti k organizaci/jednotce a skupin (automaticky z připojeného zdroje identity); kdo smí nahrávat obsah, se povoluje ručně. Audit při každé změně znalostí.
  • Přihlášení přes SSO: Microsoft Entra ID, Google Workspace; veřejný obsah i bez přihlášení.
  • Citace verze v každé odpovědi a archivace starých verzí předpisů.
  • Monitoring kvality: skóre, podíl eskalací a hodnocení jako zpětná vazba.
  • Multi-tenant hierarchie (centrála → regionální → lokální jednotky): veřejný obsah vidí všichni, interní obsah je oddělen per organizace.
  • Soukromí dat: obsah zůstává ve vaší databázi a úložišti; AI odpovídá výhradně z vašeho obsahu (RAG), veřejná spotřebitelská AI se nepoužívá.
  • Volba provozního režimu na úrovni tenanta: cloud (databáze v EU) nebo plně on-prem — obsah ani dotazy neopustí vaši infrastrukturu. Jedna instalace obslouží oba typy zákazníků současně.

Identita a řízení přístupu

Přihlášení přes existující SSO; přístupové právo je povinný filtr odvozený ze session a aplikovaný na obě větve hybridního vyhledávání ($vectorSearch i $search).

Poskytovatelé identity (NextAuth) → jedna kanonická session

OAuth / OIDCprimární login; ve sportovním nasazení např. sportnet.online + zdroj členství a rolí
Microsoft Entra IDSSO pro firemní účty zaměstnanců
Google WorkspaceSSO (alternativa)
CRM / API zdroje identityzdroj pravdy o osobách a organizačních jednotkách; mapování na companyCode, role a skupiny
Vlastní databázeúčty mimo SSO (credentials)

Principy bezpečnosti

  • Server-side only — filtr se skládá ze session, nikdy z parametrů klienta.
  • Default-deny — co není výslovně povoleno, se nevrátí; bez identity jen veřejný obsah.
  • Filtr před LLM — model vidí jen povolené chunky; nedá se obejít promptem (platí i pro citace).
  • Auto-provisioning — uživatelé, role a skupiny se zakládají a synchronizují z CRM (login + webhook).

Dva režimy nasazení

Veřejný widget

anonymní; vidí jen veřejný obsah napříč celou hierarchií.

Interní portál (SSO)

přihlášený; vidí veřejný + interní obsah jednotek, ke kterým má vztah.

Případová studie

Nasazení ve velké organizaci — sportovní svaz (SFZ)

Contineo je doménově univerzální. Takto vypadá jedno reálné nasazení do velké organizace — Slovenského fotbalového svazu a jeho podřízených svazů.

  • Tenant hierarchie: SFZ → regionální → oblastní svazy jako samostatné organizace.
  • Obsah: soutěžní a přestupní řády, rozpisy soutěží, směrnice, IT FAQ (aplikace ISSF).
  • Identita: přihlášení a CRM přes sportnet.online (OAuth) — uživatelé a role podle příslušnosti ke svazu/klubu.
  • Příklad otázky: „Může hráč nastoupit ve dvou utkáních za jeden den?“ → odpověď s citací § a verze.

Technologický stack

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