Skip to content

Knowledge Base

Die Knowledge Base ist das zentrale Wissens-System von VIA. Dokumente, FAQs, Produkte und Kalender-Eintraege werden als Vektor-Embeddings in Qdrant gespeichert und stehen den Bots als semantisch durchsuchbarer Kontext zur Verfuegung.

Architektur-Überblick

Upload/Eingabe → TextExtractor → TextChunker → MistralEmbedding → Qdrant

                                                              1024-dim Vektoren
  • Embedding-Modell: mistral-embed (1024 Dimensionen)
  • Vektor-Datenbank: Qdrant (Port 6335, Docker Container qdrant-customers)
  • Collection-Schema: tenant_{uuid}_knowledge (eine Collection pro Tenant)
  • Chunking: Zeichenbasiert, max 1000 Zeichen, min 200, Overlap 100, satzerhaltend

Haupt-Tabelle: knowledge_items

SpalteTypNullableDefaultBeschreibung
iduuidNOT NULLgen_random_uuid()Primaerschlüssel
tenant_iduuidNOT NULLTenant-Zuordnung (FK → tenants)
typevarchar(50)NOT NULLDateityp (pdf, txt, md, json, url, …)
titlevarchar(255)NULLAnzeigename
descriptiontextNULLBeschreibung / Notizen
filenamevarchar(255)NULLOriginal-Dateiname
mime_typevarchar(100)NULLMIME-Typ der Datei
file_size_bytesbigintNULL0Dateigröße in Bytes
contenttextNULLExtrahierter Textinhalt
qdrant_collectionvarchar(100)NULLQdrant Collection Name
qdrant_point_idstext[]NULLArray der Qdrant Point-IDs
embedding_modelvarchar(50)NULL'mistral-embed'Verwendetes Embedding-Modell
vectors_countintegerNULL0Anzahl erzeugter Vektoren
statusvarchar(20)NULL'pending'Status (pending, processing, ready, error, pending_review, deleted)
error_messagetextNULLFehlermeldung bei status=error
languagevarchar(10)NULL'de'Sprache des Inhalts
created_attimestamptzNULLnow()Erstellungszeitpunkt
updated_attimestamptzNULLnow()Letzte Änderung
processed_attimestamptzNULLZeitpunkt der Vektorisierung
bot_iduuidNULLLegacy Bot-Zuordnung (FK → bots, ON DELETE SET NULL)
content_typevarchar(20)NOT NULL'text'Inhaltstyp für Auto-Regeln
last_synced_content_hashtextNULLHash des letzten Sync-Inhalts
last_sync_checktimestamptzNULLLetzter Sync-Pruefzeitpunkt
sync_content_changedbooleanNULLfalseOb sich der Inhalt seit letztem Sync geändert hat
knowledge_rulesjsonbNULL'{}'Auto-generierte Regeln für buildFinalPrompt()
calendar_valid_fromdateNULLKalender: Gültig ab
calendar_valid_untildateNULLKalender: Gültig bis
calendar_time_fromvarchar(10)NULLKalender: Uhrzeit von
calendar_time_tovarchar(10)NULLKalender: Uhrzeit bis
calendar_recurrencevarchar(20)NULLKalender: Wiederholung (daily, interval, weekly, monthly, none)
calendar_intervalintegerNULLKalender: Intervall in Tagen
calendar_daysjsonbNULLKalender: Wochentage (Array)
calendar_pricevarchar(50)NULLKalender: Preis-Info
calendar_booking_urltextNULLKalender: Buchungs-Link
calendar_categoryvarchar(100)NULLKalender: Kategorie

Indizes

IndexTypSpalte(n)
knowledge_items_pkeyPRIMARY KEYid
idx_ki_content_typebtreecontent_type
idx_knowledge_items_statusbtreestatus
idx_knowledge_items_tenantbtreetenant_id
idx_knowledge_items_typebtreetype

content_type Werte

Der content_type steuert die automatische Regelgenerierung via generateAutoRules():

content_typeAuto-RegelBeschreibung
textStandard, keine spezielle Regel
pricingPREISREGELExakte Preise nennen, nicht runden, keine Rabatte erfinden
faqFAQ-REGELAntwort nah an der Vorlage, nicht abweichen
policyRICHTLINIEN-REGELStrikt an Richtlinie halten, nicht frei interpretieren
scheduleZEITPLAN-REGELExakte Zeiten/Daten, keine Termine erfinden
contactKONTAKT-REGELNur angegebene Kontaktdaten weitergeben
productPRODUKT-REGELProdukte anhand vorhandener Infos beschreiben

knowledge_rules (JSONB)

Das Feld knowledge_rules wird beim Onboarding gesetzt und von generateAutoRules() in Regel-Strings umgewandelt. Diese Regeln fliessen in buildFinalPrompt() ein.

javascript
// Struktur:
{
  content_type: 'pricing',      // Einer der obigen Werte
  accuracy: 'exact',            // 'exact' oder 'approximate'
  usage_hint: 'Nur für ...',   // Freitext-Hinweis
  restrictions: '...',          // Einschraenkungen
  priority: 8                   // Prioritaet (1-10)
}

accuracy-Werte:

  • exact — Wortgenaue Wiedergabe, keine Umformulierung von Zahlen/Fakten
  • approximate — Sinngemaeß formulieren erlaubt, aber Fakten beibehalten

Bot-Zuweisung: knowledge_bot_assignments

Jedes Knowledge-Item muss mindestens eine Bot-Zuweisung haben. Ohne Zuweisung wird das Item vom Bot nicht gefunden, auch wenn es vektorisiert ist.

SpalteTypNullableDefaultBeschreibung
iduuidNOT NULLuuid_generate_v4()Primaerschlüssel
knowledge_item_iduuidNOT NULLFK → knowledge_items (ON DELETE CASCADE)
bot_iduuidNOT NULLFK → bots (ON DELETE CASCADE)
tenant_iduuidNOT NULLFK → tenants (ON DELETE CASCADE)
created_attimestamptzNULLCURRENT_TIMESTAMPErstellungszeitpunkt
item_typevarchar(20)NULL'document'Typ der Zuweisung

Unique Constraint: (knowledge_item_id, bot_id, item_type) — verhindert doppelte Zuweisungen.

Kritische Regel

Ein Knowledge-Item ohne Eintrag in knowledge_bot_assignments ist unsichtbar für alle Bots. Das Backend erzwingt Auto-Assign bei Erstellung.

Unter-Tabelle: knowledge_faqs

Strukturierte FAQ-Eintraege, verknuepft mit einem Knowledge-Item.

SpalteTypNullableDefaultBeschreibung
iduuidNOT NULLgen_random_uuid()Primaerschlüssel
tenant_iduuidNOT NULLFK → tenants (ON DELETE CASCADE)
knowledge_item_iduuidNULLFK → knowledge_items (ON DELETE SET NULL)
questiontextNOT NULLDie Frage
answertextNOT NULLDie Antwort
categoryvarchar(100)NULLKategorie
tagstext[]NULLTags als Array
priorityintegerNULL0Sortier-Prioritaet
is_activebooleanNULLtrueAktiv/Inaktiv
created_attimestamptzNULLnow()Erstellungszeitpunkt
updated_attimestamptzNULLnow()Letzte Änderung

Unter-Tabelle: knowledge_products

Strukturierte Produktdaten, verknuepft mit einem Knowledge-Item.

SpalteTypNullableDefaultBeschreibung
iduuidNOT NULLgen_random_uuid()Primaerschlüssel
tenant_iduuidNOT NULLFK → tenants (ON DELETE CASCADE)
knowledge_item_iduuidNULLFK → knowledge_items (ON DELETE SET NULL)
namevarchar(255)NOT NULLProduktname
descriptiontextNULLBeschreibung
skuvarchar(100)NULLArtikelnummer
pricenumeric(10,2)NULLPreis
currencyvarchar(3)NULL'EUR'Waehrung
price_infotextNULLZusaetzliche Preis-Infos
categoryvarchar(100)NULLKategorie
tagstext[]NULLTags als Array
is_availablebooleanNULLtrueVerfügbar?
availability_infotextNULLVerfügbarkeits-Hinweis
image_urltextNULLBild-URL
is_activebooleanNULLtrueAktiv/Inaktiv
created_attimestamptzNULLnow()Erstellungszeitpunkt
updated_attimestamptzNULLnow()Letzte Änderung

Qdrant Konfiguration

ParameterWert
URLhttp://localhost:6335 (ENV: QDRANT_CUSTOMERS_URL)
Collection-Nametenant_{uuid}_knowledge
Vektor-Dimension1024
Embedding-Modellmistral-embed
Chunk-Größemax 1000 Zeichen
Chunk-Minimum200 Zeichen
Overlap100 Zeichen
SatzerhaltendJa (respectSentences: true)

KB Onboarding Checkliste

Der KBOnboardingService prueft automatisch 6 Kriterien (gespeichert in tenants.kb_onboarding als JSONB):

CheckFeldBestanden wenn...
Preisdokument vorhandenhas_structured_pricesMindestens 1 Item mit content_type='pricing'
FAQ vorhandenhas_faqItem mit content_type='faq' ODER Eintraege in knowledge_faqs
Kontaktdaten in KBhas_contact_infoContent enthaelt Keywords: telefon, e-mail, kontakt, anruf
Keine E-Mail-Dumpsno_email_dumpsKeine Items mit status='pending_review'
PII-Scan bestandenpii_scan_passedKeine Items mit status='pending_review'
Bot-Zuweisungen komplettbot_assignments_completeAlle nicht-gelöschten Items haben Bot-Zuweisung

Wenn alle 6 Checks bestanden sind, wird completed_at gesetzt. Faellt ein Check spaeter durch, wird completed_at zurückgesetzt auf null.

Verarbeitungs-Pipeline

1. Upload (PDF/TXT/MD/JSON/URL)
2. TextExtractor → Rohtext
3. KnowledgeValidator → PII-Scan (warnt, blockiert nicht)
4. DB-Insert in knowledge_items (status='pending')
5. TextChunker → Chunks (1000 Zeichen, 100 Overlap)
6. MistralEmbedding → 1024-dim Vektoren (NaN/Infinity Check!)
7. Qdrant Upsert → tenant_{uuid}_knowledge
8. DB-Update: status='ready', vectors_count, qdrant_point_ids
9. knowledge_bot_assignments INSERT (Auto-Assign!)