Taris: UI-asistent, pri katerem podatki ostanejo pri stranki
TL;DR. Taris je UI-asistent, pri katerem podatki stranke ne potujejo k ponudniku modela. Osnovno načelo: model je zamenljiv vtičnik za stabilnim vmesnikom in ne središče arhitekture. V ozadju so od ponudnika neodvisen razdelilnik zahtev za LLM, hibridni RAG (BM25 + vektorsko iskanje + RRF + ponovno razvrščanje s cross-encoderjem), večnajemniški Postgres s pgvector in po želji lokalni modeli prek Ollame. V članku opišemo, kako je Taris zgrajen, zakaj je zgrajen prav na ta način in kje to prinaša prednosti malim in srednjim podjetjem (MSP) v EU.
1. Problem: „Vzemimo GPT-4 in pozabimo na vse drugo“
Ko lastnik manjšega podjetja vpraša, katerega UI-asistenta naj uvede, običajno dobi enega od dveh skrajnih odgovorov:
- „Vzemite ChatGPT, Copilot Studio ali Microsoft 365, tam je vse.“ Priročno, vendar podatki odidejo k ponudniku, prilagoditve so omejene, stroški rastejo nepregledno, prehod na drugo platformo pa pomeni popolno selitev.
- „Vse vam bomo zgradili od začetka z LangChainom.“ Počasi in drago, leto pozneje pa se izkaže, da je velik del kode zgolj „lepilo“ za menjavo modelov, ki ga nihče noče vzdrževati.
Taris je tretja pot: osnova v obliki izdelka (razdelilnik modelov, hibridni RAG, večnajemniški Postgres, adapterji za kanale), ki jo namestimo pri stranki in ji jo tudi prepustimo. Ni SaaS in ni gradnja od nič, temveč polizdelek, ki ga je mogoče pregledno prilagoditi.
2. Za koga je to pomembno
- MSP z 10–500 zaposlenimi, ki so že nabrala veliko dokumentov, pravilnikov in zgodovine strank, nimajo pa lastnih strokovnjakov za UI.
- Regulirane panoge (zdravstvo, varnost in zdravje pri delu, pravno svetovanje), kjer lahko stavek „naši podatki so pristali pri OpenAI“ pomeni globo.
- Zagonska podjetja, ki potrebujejo skupno osnovo za asistente pri več notranjih primerih uporabe.
3. Pogosta napaka
Kaj pogosto vidimo pri „pilotih“, ki so se začeli pred našim prihodom:
- Priključen je bil en sam API. Ko je ponudnik dvignil cene, na selitev ni bil pripravljen nihče.
- Vse je bilo stlačeno v en velik poziv. Učinek „Lost in the Middle“ (Liu et al., 2023) naredi svoje in model „pozabi“ sredino konteksta.
- RAG je bil zgrajen samo na vektorskih vložitvah, zato točnih šifer in identifikatorjev ni mogoče najti.
- Evalvacijskega nabora ni, zato nihče ne more reči, ali je po zadnji „izboljšavi poziva“ kakovost res boljša.
- Dokumenti stranke ležijo v tujem oblaku brez pogodbe o obdelavi podatkov (DPA), pravni pregled pa se odlaga.
4. Tehnični pristop: kaj je v Tarisu
Arhitektura ima štiri neodvisne plasti:
flowchart LR
subgraph Kanali
TG[Bot za Telegram]
WEB[Spletni vmesnik / PWA]
VOICE[Glas]
API[REST API]
end
subgraph Jedro
GW[FastAPI Gateway]
ORCH[Orkestrator agentov]
DISP[Razdelilnik LLM]
KB[Storitev baze znanja]
AUTH[Overjanje + RBAC]
end
subgraph Shramba
PG[(Postgres + pgvector)]
OBJ[(MinIO / S3)]
LOG[(Revizijska sled)]
end
subgraph Modeli
LOCAL[Ollama / llama.cpp]
CLOUD[OpenAI / Anthropic / Gemini / OpenRouter]
end
TG --> GW
WEB --> GW
VOICE --> GW
API --> GW
GW --> AUTH --> ORCH
ORCH --> KB --> PG
ORCH --> DISP
DISP --> LOCAL
DISP --> CLOUD
ORCH --> LOG
Bistvo je v tem, da je mogoče vsako plast zamenjati. Kanali so adapterji, model je vtičnik, shramba je zaledje, orkestrator pa je edino mesto, kjer je poslovna logika. Če OpenAI jutri potroji cene, namestitev Tarisa preklopi na drugega ponudnika s spremembo ene same konfiguracijske datoteke.
4.1. Razdelilnik LLM
class LLMProvider(Protocol):
async def complete(
self,
messages: list[ChatMessage],
*,
max_tokens: int,
temperature: float,
tools: list[Tool] | None = None,
) -> ChatCompletion: ...
Podprtih je šest ponudnikov: OpenAI, Anthropic, Gemini, OpenRouter, Ollama in llama.cpp. Usmerjanje se nastavi v datoteki YAML:
default: openrouter:openai/gpt-4o-mini
routes:
- match: { task: rerank }
use: ollama:bge-reranker-base
- match: { sensitive: true }
use: ollama:llama3.1:8b
fallback:
- openrouter:anthropic/claude-3-5-sonnet
- ollama:llama3.1:8b
4.2. Hibridni RAG z RRF
Iskanje poteka v treh vzporednih korakih:
- Leksikalno (BM25): Postgres FTS z jezikovnimi analizatorji za RU/EN/DE/SL.
- Vektorsko: kosinusna podobnost v pgvector, privzeto z
text-embedding-3-small, pri lokalni namestitvi zbge-m3. - Utež metapodatkov: točno ujemanje oznak (
product,section,last_updated).
Rezultate združimo z metodo Reciprocal Rank Fusion:
$$ \text{score}(d) = \sum_{i \in \text{retrievers}} \frac{1}{k + \text{rank}_i(d)}, \quad k = 60 $$
Sledi ponovno razvrščanje s cross-encoderjem (bge-reranker-base) na top-5. Izmerjeni učinek na našem internem referenčnem naboru s področja varnosti pri delu: recall@5 0,71 → 0,88 (RRF v primerjavi s samim vektorskim iskanjem) in delež utemeljenih odgovorov +0,07 po ponovnem razvrščanju. Razlika ni kozmetična, saj loči „uporabno“ od „stranki moramo vrniti denar“.
4.3. Večnajemniški Postgres z RLS
CREATE POLICY tenant_isolation ON chunks
USING (tenant_id = current_setting('app.tenant_id')::int);
Vsaka povezava pred poizvedbo nastavi SET app.tenant_id = $1. Podatkov druge stranke ni mogoče pomotoma prebrati, za to poskrbi podatkovna baza sama.
5. Tabela: katere komponente je mogoče zamenjati
| Plast | Privzeto | Alternativa | Strošek zamenjave |
|---|---|---|---|
| Vložitve | text-embedding-3-small |
bge-m3 |
konfiguracija + ponovno indeksiranje |
| Ponovno razvrščanje | bge-reranker-base |
mxbai-rerank |
konfiguracija |
| Vektorska shramba | pgvector | Qdrant | docker-compose + migracija |
| LLM | gpt-4o-mini |
claude-3-5-sonnet, llama3.1:8b |
konfiguracija |
| Kanal | Telegram | splet / Slack / WhatsApp | adapter, približno 200 vrstic |
| Shramba datotek | MinIO | S3 / Nextcloud | konfiguracija |
| Namestitev | Docker Compose | Kubernetes / Nomad | manifesti |
6. Primer iz prakse SINTARIS
Izdelek Worksafety Superassistant je primer Tarisa v resnični uporabi. Naloga:
- notranji asistent za predpise s področja varnosti pri delu (približno 3000 strani PDF);
- klepetalni bot v Telegramu za delavce v proizvodnji (v ruščini in nemščini);
- popolnoma lokalna namestitev (zahteva pooblaščene osebe za varstvo podatkov).
Tehnična izvedba:
- Taris v konfiguraciji OpenClaw na dveh strežnikih: glavnem (Ubuntu 24.04, 64 GB RAM, RTX 4090) in rezervnem.
- Vložitve:
bge-m3; generiranje:llama3.1:8b-instruct(zadošča za ruščino in nemščino); rezervni model:qwen2.5:14b. - Bot za Telegram za lokalnim NAT-om, brez oblaka.
- Referenčni nabor: 120 vprašanj z referenčnimi navedbami.
Metrike po 90 dneh:
- Recall@5: 0,86 na referenčnem naboru.
- Natančnost navedb virov: 92 %.
- Mediana zakasnitve: 1,9 s.
- Stroški LLM: 0 € (vse teče lokalno).
- Stroški infrastrukture: približno 120 € na mesec za elektriko in amortizacijo.
Podrobnosti: Worksafety § 6 RAG pipeline in OpenClaw § 8 AI dispatch.
7. Kontrolni seznam (15 točk) za izbiro UI-asistenta v MSP
- Odvisnost od ponudnika je preverjena: ali lahko ponudnika LLM zamenjate v enem tednu?
- Podatki: kje so dokumenti stranke fizično shranjeni?
- Vložitve: kje so shranjene? (Pogosto pozabljeno: tudi te so izpeljane iz osebnih podatkov.)
- Pogodba o obdelavi podatkov (DPA) je podpisana z vsakim ponudnikom LLM, ki ga uporabljate.
- Evalvacijski nabor: ali ga imate in koliko vprašanj vsebuje?
- Navajanje virov: ali sistem v odgovorih navaja vire?
- Delež utemeljenih odgovorov: ali ga merite? (Če ga ne, nihče ne ve, ali si model izmišljuje.)
- Regresijski testi iskanja: ali jih poženete po vsaki spremembi poziva?
- Ločevanje strank: RLS na ravni podatkovne baze, ne le „dogovor v kodi“?
- Lokalni modeli: ali obstaja načrt B, če oblak odpove?
- Strošek na žeton: ali ga spremljate sproti?
- Zahteve posameznikov (DSAR) in izbris: so vgrajeni v kodo, ne pa urejeni ročno?
- Revizijska sled: ali obstaja, je nespremenljiva in se hrani predpisani čas?
- Kanali: ali nov kanal pomeni manj kot 500 vrstic kode ali predelavo jedra?
- Dokumentacija: v katerem jeziku je, za koga in kako pogosto se posodablja?
8. Tveganja
- Skušnjava najzmogljivejših modelov. Ekipa se navadi na Sonnet, potem pa stranka zahteva lokalno namestitev in sistem je treba prilagoditi modelu velikosti 8B. Rešitev: od prvega dne testirajte na modelu 8B, najzmogljivejše modele pa uporabljajte le tam, kjer je korist dokazana.
- Zapletenost razdelilnika. Več ko je podprtih ponudnikov, več je robnih primerov. Naše pravilo: novega ponudnika dodamo šele, ko ga zahteva stranka.
- Vložitve niso prenosljive. Ob zamenjavi modela za vložitve je treba vse znova indeksirati, zato za to načrtujte čas.
- Kakovost v več jezikih.
bge-m3se dobro obnese v jezikih EU in v ruščini, v nemščini in slovenščini pa je kakovost nižja kot v angleščini. Preverite jo na svojem referenčnem naboru.
9. Kaj storiti naprej
Če že imate UI-asistenta in razmišljate o zamenjavi, izvedemo analizo priložnosti za UI. Če želite preizkusiti Taris, je na voljo pilot z UI, ki traja 4–8 tednov in ima vnaprej določen obseg. Obseg in ceno določimo po uvodnem pogovoru (glejte pakete).
Če želite najprej brati, si v bazi znanja oglejte poglavji Taris (celoten opis) in OpenClaw (topologija lokalne namestitve).
10. Viri
- Lewis, P. et al. (2020). Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks. arXiv:2005.11401.
- Karpukhin, V. et al. (2020). Dense Passage Retrieval for Open-Domain Question Answering. arXiv:2004.04906.
- Cormack, G., Clarke, C., Buettcher, S. (2009). Reciprocal Rank Fusion outperforms Condorcet and individual rank learning methods. SIGIR '09.
- Liu, N. F. et al. (2023). Lost in the Middle: How Language Models Use Long Contexts. arXiv:2307.03172.
- BAAI (2024). BGE-M3: One-stop multi-lingual, multi-functionality, multi-granularity text embeddings.
- pgvector: https://github.com/pgvector/pgvector
- Ollama: https://ollama.com
SINTARIS izvaja analize priložnosti za UI, pilote z UI in namestitve Tarisa za MSP v EU. Uvodni pogovor je brezplačen in traja 30 minut.