Gosoft Connect - tekoälychat, joka nojaa asiakkaan dokument­teihin

Multi-tenant-widget-palvelu, jonka tekoälychat vastaa kunkin asiakkaan omasta tietopohjasta - koko hakupino itse ylläpidettynä yhdellä CPU-nodella.

Viktor Sundberg · viktorsundberg.me/fi/work/connect/

Mikä se on

Gosoft Connect on multi-tenant-SaaS, jonka olen suunnitellut ja rakentanut yksin GoSoftissa, omassa yhtiössäni: upotettavia verkkosivu­widgettejä - tekoälychat, livechat, lomakkeet, popupit - ja hallinta­portaali.

Jokaisella asiakas­työtilalla on tietopohja, jota täytetään neljällä tavalla: liittämällä tekstiä, noutamalla URL, lataamalla tiedostoja tai indeksoimalla kokonainen sivukartta. Asiakkaan sivuston tekoälychat vastaa kävijöiden kysymyksiin tämän tietopohjan perusteella ja striimaa vastaukset token kerrallaan.

Avustaja toimii sisäisten työkalu­kutsujen kautta: käytössä ovat hakutyökalut, laskin sekä työkalut yritys­tietojen hakuun, liidien keräämiseen ja keskustelun siirtoon ihmiselle. Jokaisen asia­sisältöisen viestin kohdalla malli pakotetaan ensimmäisellä kierroksella kutsumaan työkalua, joten vastaukset perustuvat asiakkaan dataan eivätkä mallin oletuksiin.

Chatin ympärillä ovat kooste­sähköpostit, lomake­vastausten tekoäly­tiivistelmät, keskustelujen luokittelu, öisin ajettavat raportit kysymyksistä, joihin botti ei osannut vastata, sekä syötteen ja vastausten moderointi.

Hakuputki

Vastaukset pohjautuvat hybridi­hakuun: tiheät vektorit pgvectorissa ja tekstihaun pisteytys yhdistetään reciprocal rank fusion -menetelmällä, minkä jälkeen cross-encoder järjestää tulokset uudelleen, dokumentti­kohtaisella moni­muotoisuus­rajalla ja kieli­tietoisella haulla suomen-, ruotsin- ja englannin­kieliseen sisältöön. Paloittelu on kappale­tietoista, ja jokainen pala saa konteksti­otsikon; sisältö­hashien ansiosta muuttumattomia dokumentteja ei koskaan upoteta uudelleen.

kävijän kysymysyksi Linux-node, pelkkä CPUtiheä hakubge-m3 → pgvector HNSWtekstihakutsvector, BM25-tyyliinPostgreSQLyksi tietokanta kaikellereciprocal rank fusionuudelleenjärjestys, cross-encoderbge-reranker-v2-m3, q8monimuotoisuusrajaenintään 2 palaa per dokumenttiLLMainoa ulkoinen kutsuvastaus, striimattuna token kerrallaankävijän kysymysyksi Linux-node, pelkkä CPUtiheä hakubge-m3 → pgvector HNSWtekstihakutsvector, BM25-tyyliinPostgreSQLyksi tietokanta kaikellereciprocal rank fusionuudelleenjärjestys,cross-encoderbge-reranker-v2-m3, q8monimuotoisuusrajaenintään 2 palaa per dokumenttiLLMainoa ulkoinen kutsuvastaus,striimattuna token kerrallaan
Yksinkertaistettu hakuputki.

Stack ja infrastruktuuri

Tarkoituksella pieni: kaikki pyörii yhdellä Linux-nodella, pelkällä CPU:lla. Upotusmalli (bge-m3) ja uudelleen­järjestäjä (bge-reranker-v2-m3) ajetaan paikallisesti ONNX:llä - ei GPU:ta, ei embedding-API:a. Asiakkaan dokumentit lähtevät koneelta täsmälleen yhtä asiaa varten: itse LLM-kutsua (OpenAI, malli valittavissa työtila­kohtaisesti), ja kutsun kattaa palvelun­tarjoajan kanssa tehty tietojen­käsittely­sopimus. Vektori­varasto on tavallinen PostgreSQL pgvectorilla - yksi tietokanta kaikelle. Bun ja Hono taustalla, Solid.js-portaali, nginx edessä.

Insinöörityö

Luvut, jotka voin julkaista, ovat insinööri­lukuja. Uudelleen­järjestäjän kvantisointi pudotti haun 14 sekunnista 4,1:een CPU:lla, itse järjestys­vaiheen 5,6:sta 1,1:een. Varhainen kuormitus­testi pudotti kaksi kymmenestä saman­aikaisesta chatista ja kaatoi prosessin, kun muistin­käyttö oli 10,4 GB; inferenssi­semaforin ja erä­paloittelun jälkeen sama testi palveli 10/10 muistihuipun ollessa 6,8 GB, ilman yhtäkään uudelleen­käynnistystä. Tuotannossa kesäkuusta 2026 lähtien.

Mallit valitaan automaattisella arviointi­sarjalla. Sarja kulkee samaa koodipolkua kuin kävijän kysymys oikeassa chatissa ja jää koodikantaan regressio­testiksi. GoSoftissa käytämme tekoäly­agentteja myös sisäisesti, ohjelmisto­kehityksessä ja päivittäisessä työssä.