Hem

Om Chatbotten

Chatbotten är en AI-baserad assistent som hjälper dig att navigera och söka i Smart Built Toolbox.

Funktioner

  • Intelligent sökning - Chatbotten kan söka igenom projektdatabasen och hitta relevant information baserat på dina frågor.
  • Naturligt språk - Du kan ställa frågor på svenska eller engelska i naturligt språk.
  • Kontextmedveten - Chatbotten förstår sammanhanget i din fråga och kan ge relevanta svar.

Hur använder jag chatbotten?

  1. Klicka på chatbubble-ikonen i nedre högra hörnet
  2. Skriv din fråga i textfältet
  3. Tryck på Enter eller klicka på skicka-knappen
  4. Vänta på svar från chatbotten

Tips för bästa resultat

  • Var specifik i dina frågor
  • Använd relevanta nyckelord
  • Om du inte får det svar du förväntar dig, försök omformulera din fråga

Begränsningar

Chatbotten kan hjälpa dig med information som finns i systemet, men har begränsningar:

  • Den kan inte utföra ändringar i databasen
  • Den kan inte ge råd utanför sitt kunskapsområde
  • Svaren baseras på tillgänglig data i systemet

Teknisk Arkitektur

Här beskriver vi hur chatbotten faktiskt fungerar under huven. Den bygger på en RAG-arkitektur (Retrieval-Augmented Generation).

1. Datainsamling

Vi hämtar information från flera källor automatiskt:

  • Webbsidor: Vi skrapar HTML-sidor och plockar ut texten (tar bort scripts, CSS och taggar). PDF-länkar på sidorna hittas automatiskt.
  • PDF:er: Vi försöker först läsa texten direkt. Om det är en skannad PDF utan text använder vi LlamaParse med OCR.

All text sparas på projektnoden i Neo4j (websiteText, pdfText).

2. Chunking och Embedding

Texten delas upp i mindre bitar (chunks) med lite överlapp så att sammanhanget bevaras:

  • Chunk-storlek: 2000 tecken
  • Överlapp: 200 tecken

Varje chunk görs om till en vektor (en lista med 3072 tal) med en embedding-modell. Matematiskt:

E:TR3072E: T \rightarrow \mathbb{R}^{3072}

där TT är texten och resultatet är en 3072-dimensionell vektor. Dessa vektorer sparas i PostgreSQL med pgvector.

3. Sökning

När en användare skickar ett meddelande i chatten görs frågan också om till en vektor vq=E(q)\mathbf{v}_q = E(q). Sen hittar vi liknande dokument genom att räkna ut avståndet mellan vektorerna (L2-distans):

d(vq,vd)=vqvd2=i=13072(vq,ivd,i)2d(\mathbf{v}_q, \mathbf{v}_d) = ||\mathbf{v}_q - \mathbf{v}_d||_2 = \sqrt{\sum_{i=1}^{3072} (v_{q,i} - v_{d,i})^2}

Vi filtrerar bort resultat med avstånd över 1.2 och tar max 3 chunks per projekt för att få en bra mix.

4. Kontext till AI:n

De bästa matchningarna skickas med som kontext i prompten till AI-modellen. På så sätt kan den svara baserat på riktig projektdata istället för att gissa.

5. Tool Calling

AI-modellen kan också anropa verktyg för att hämta mer data:

VerktygVad den gör
searchProjectsSöker projekt med vektorsökning
searchNodesTextsökning via Meilisearch (projekt, organisationer, personer etc.)
getNodeDetailsHämtar detaljer och relationer från Neo4j
getCurrentViewNodesHämtar info om noderna användaren tittar på just nu

6. Svar

Till slut sätter AI-modellen ihop ett svar baserat på:

  1. Användarens fråga
  2. Matchade chunks från vektorsökningen
  3. Data från tool calls
  4. Tidigare meddelanden i konversationen

Svaret streamas tillbaka med markdown-formatering och länkar till projekten.

Systemdiagram

┌─────────────────────────────────────────────────────────────────┐
│                    INDEXERINGSFLÖDE (Batch)                     │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────┐     ┌──────────────┐     ┌─────────────────┐  │
│  │  Webbsidor  │────▶│   Chunking   │────▶│   Embedding     │  │
│  │  PDF-filer  │     │  2000 tecken │     │   Embedding     │  │
│  │  (LlamaParse)     │  200 overlap │     │   (3072-dim)    │  │
│  └─────────────┘     └──────────────┘     └────────┬────────┘  │
│                                                     │          │
│                                                     ▼          │
│                                            ┌─────────────────┐ │
│                                            │    pgvector     │ │
│                                            │   (PostgreSQL)  │ │
│                                            └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                     FRÅGEFLÖDE (Runtime)                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────┐     ┌──────────────┐     ┌─────────────────┐  │
│  │ Användar-   │────▶│   Embedding  │────▶│  L2-distans     │  │
│  │ fråga (q)   │     │   Embedding  │     │  sökning        │  │
│  └─────────────┘     └──────────────┘     └────────┬────────┘  │
│                                                     │          │
│                      ┌──────────────┐               │          │
│                      │ Tool Calling │◀──────────────┤          │
│                      │ - searchNodes│               │          │
│                      │ - getDetails │               │          │
│                      └──────┬───────┘               │          │
│                             │                       ▼          │
│                             │              ┌─────────────────┐ │
│                             └─────────────▶│   AI-modell     │ │
│                                            │ + Streaming     │ │
│                                            └────────┬────────┘ │
│                                                     │          │
│                                                     ▼          │
│                                            ┌─────────────────┐ │
│                                            │  Formaterat     │ │
│                                            │  Markdown-svar  │ │
│                                            └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘