IrisRAG - Technische Dokumentation

1. Architekturueberblick

IrisRAG ist eine RAG-Anwendung auf InterSystems IRIS mit gemischter Implementierung in:

Die Anwendung besteht aus vier technischen Hauptbereichen:

Bereich Komponenten
Datenmodell UserRag, GruppeRag, BereichRag, Join-Klassen
Wissensspeicher RAGDokumente, RAGDokumenteChunks
Retrieval/LLM LLMProxy, LLMProxyEntwicklerTests
Web Web.Dispatcher, Web.Login, Web.Dashboard, Web.Admin, Web.AdminLogin

2. Datenmodell

2.1 Zugriffsmodell

UserRag
  -> UserGruppeRag
     -> GruppeRag
        -> BereichGruppeRag
           -> BereichRag

2.2 Dokumentmodell

RAGDokumente
  -> RAGDokumenteChunks

RAGDokumente speichert Metadaten, Quellpfad, Hash, Zeitstempel und Bereich. RAGDokumenteChunks speichert Chunk-Text und Vektor-Embedding.

2.3 Wichtige Beziehungen

Klasse Beziehung
BereichRag 1:n zu RAGDokumente
RAGDokumente children zu RAGDokumenteChunks
UserRag / GruppeRag m:n ueber UserGruppeRag
GruppeRag / BereichRag m:n ueber BereichGruppeRag

3. Klassenlandschaft

Klasse Typ Aufgabe
IrisRAG.RAGDokumente %Persistent Import, Staging, Dateityp-Verarbeitung, Embedding-Orchestrierung
IrisRAG.RAGDokumenteChunks %Persistent Chunk-Text und Vektoren
IrisRAG.LLMProxy %RegisteredObject Retrieval, Kontextaufbau, LLM-Aufruf
IrisRAG.LLMProxyEntwicklerTests %RegisteredObject Benchmarking
IrisRAG.UserRag %Persistent Benutzer
IrisRAG.GruppeRag %Persistent Gruppen
IrisRAG.BereichRag %Persistent Bereiche
IrisRAG.UserGruppeRag %Persistent User-Gruppen-Zuordnung
IrisRAG.BereichGruppeRag %Persistent Bereich-Gruppen-Zuordnung
IrisRAG.Web.Dispatcher %CSP.REST Routing, Login-Guards, Admin-Aktionen
IrisRAG.Web.Dashboard %CSP.Page Benutzeroberflaeche fuer Fragen
IrisRAG.Web.Login %CSP.Page regulare Login-Seite
IrisRAG.Web.Admin %CSP.Page Admin-Konsole inkl. Dokumentimport
IrisRAG.Web.AdminLogin %CSP.Page Admin-Login

4. Import-Pipeline

4.1 Einstiegspunkte

IrisRAG.RAGDokumente stellt mehrere Importwege bereit:

Methode Zweck
ReadFolder(folder, bereich) Verzeichnisimport im Container
AddDocument(datei, verzeichnis, bereich) einzelnes Dokument ueber vorhandenen Dateipfad
ImportUploadedDocument(name, base64, bereich) Browser-Upload ueber Dispatcher
ImportUrlAsDocument(url, bereich) Webseitenimport mit HTML-zu-Markdown
ImportStagedDocument(name, pfad, bereich) Nachverarbeitung einer bereits abgelegten Datei
ImportByPath(relpath, bereich) Import per relativem Pfad innerhalb von SRCVOLUMEPATH
ImportByAbsolutePath(abspath, bereich) Import per beliebigem Originalpfad; Datei muss zuvor manuell nach SRCVOLUMEPATH kopiert worden sein

4.2 Dateityp-Verarbeitung

PDF

Textbasierte Formate

HTML / HTM

4.3 Browser-Upload

Technischer Ablauf:

  1. Web.Admin liest die lokale Datei mit JavaScript ueber FileReader.
  2. Der Inhalt wird als Base64 an /admin/save gesendet.
  3. Web.Dispatcher.DoAdminSave() ruft ImportUploadedDocument(...) auf.
  4. IRIS schreibt die Datei in das konfigurierte Upload-Staging.
  5. Danach folgt die normale Chunk-/Embedding-Pipeline.

4.4 URL-Import

Technischer Ablauf:

  1. Admin sendet URL + Bereich an /admin/save.
  2. Web.Dispatcher ruft ImportUrlAsDocument(...) auf.
  3. IRIS laedt die Ziel-URL serverseitig per urllib.request.
  4. HTML wird mit trafilatura zu Markdown konvertiert.
  5. Der Dateiname wird aus Pfad + 8-stelligem SHA256-Kurzhash der vollen URL gebildet (z. B. DocBook.UI.Page_a3f7b291.md). Damit erzeugen URLs mit gleichem Pfad aber unterschiedlichen Query-Parametern keine Dateikollisionen.
  6. Eine Datei wird unter UPLOADROOTDIR/url gespeichert.
  7. ImportStagedDocument(...) fuehrt danach den regulaeren RAG-Import aus.
  8. Die Original-URL wird in der Property QuelleUrl des Dokuments gespeichert.

4.5 Upload-Staging

Parameter:

UPLOADROOTDIR = /usr/irissys/mgr/irisrag_uploads

Struktur:

/usr/irissys/mgr/irisrag_uploads/upload
/usr/irissys/mgr/irisrag_uploads/url

Wichtig: Die physische Ablage ist absichtlich nicht nach Bereich segmentiert. Der Bereich bleibt als IRIS-Metadatum am Dokument erhalten.

4.6 Pfadbasierter Import

ImportByPath(vstrRelPath, vstrBereich) nimmt einen Pfad relativ zu SRCVOLUMEPATH entgegen und leitet die Datei an die normale Staging-Pipeline weiter.

ImportByAbsolutePath(vstrAbsPath, vstrBereich) nimmt einen beliebigen Originalpfad des Host-Systems entgegen (z. B. /Users/admin/Documents/Projekt/bericht.pdf). Die Datei wird nicht direkt unter dem angegebenen Pfad gesucht, sondern ueber den Dateinamen in SRCVOLUMEPATH aufgefunden. Der Originalpfad wird als Quellverweis gespeichert und im Admin-Bereich angezeigt. Das erlaubt, die urspruengliche Herkunft der Datei nachzuvollziehen, obwohl die physische Kopie innerhalb des Containers liegt.

Validierung in ImportByAbsolutePath:

  1. Bereich muss in IRIS vorhanden sein.
  2. SRCVOLUMEPATH muss konfiguriert sein.
  3. Der Dateiname wird aus dem angegebenen Originalpfad extrahiert.
  4. Die Datei wird unter SRCVOLUMEPATH/dateiname gesucht. Fehlt sie dort, wird ein erklaerungsfaehiger Fehler zurueckgegeben.
  5. Der weitere Ablauf entspricht ImportStagedDocument(...).

Parameter:

SRCVOLUMEPATH = /Users/admin/IRIS_Data/src

4.7 copy_to_rag – Hilfsprogramm fuer den Dateitransfer

copy_to_rag.py ist ein optionales Python-Hilfsprogramm (Tkinter-GUI), das den Dateitransfer in das Container-Volume vereinfacht. Es ist kein Bestandteil des IRIS-Kernsystems und nur als Bedienerleichterung gedacht.

Starten: Doppelklick auf copy_to_rag.command im Finder (kein Terminal erforderlich).

Ablauf:

  1. Nativer macOS-Dateidialog oeffnet sich zur Dateiauswahl.
  2. Unterstuetzte Typen: .pdf, .txt, .md, .html, .htm, .json, .xml, .csv.
  3. Die gewaehlte Datei wird nach SRCVOLUMEPATH (/Users/admin/IRIS_Data/src/) kopiert.
  4. Der Originalpfad wird automatisch in die Zwischenablage gelegt.
  5. Im Admin-Bereich unter Datei per Pfad importieren kann der Originalpfad direkt eingefuegt werden (Cmd+V).

Hinweis: Das Programm ist nicht zwingend erforderlich. Dateien koennen alternativ manuell in das Volume-Verzeichnis kopiert und der Pfad direkt im Admin-Bereich eingetragen werden.

4.8 Hash- und Update-Logik

Vor der eigentlichen Speicherung wird fuer jede Datei ein SHA256-Hash gebildet.

Die Logik lautet:

  1. gleicher Pfad + gleicher Dateiname + gleicher Hash -> nichts neu speichern
  2. gleicher Pfad + gleicher Dateiname + anderer Hash -> UpdateEmbeddings(...)
  3. neuer Pfad/Dateiname -> SaveEmbeddings(...)

5. Chunking und Embeddings

5.1 Parameter

Parameter Wert
CHUNKSIZE 700
CHUNKOVERLAP 150
EMBEDDINGDIM 768
OLLAMAMODEL nomic-embed-text
OLLAMAURL http://host.docker.internal:11434/api/embeddings
OLLAMATIMEOUT 20

5.2 Persistenz

RAGDokumente speichert:

RAGDokumenteChunks speichert:

5.3 Rebuild-Funktionen

Methode Zweck
RebuildChunksForSavedDocument() Chunks fuer ein bestehendes Dokument neu erzeugen
RebuildChunksForSavedDocumentByIdInfo(id) Rebuild fuer Dokument-ID mit Textinfo
RebuildAllDocumentsInfo() Rebuild aller Dokumente
GetChunkCoverageInfo() Uebersicht ueber Chunks je Dokument

6. Retrieval- und Antwortpipeline

6.1 LLMProxy-Parameter

Parameter Wert
MODEL llama3
URL http://host.docker.internal:11434/api/chat
CONTEXTCHUNKS 9
CONTEXTCANDIDATES 256
MAXCHUNKSPERDOCUMENT 4
MINMATCHTERMS 2
MINMATCHSCORE 5
MINSOURCESCORE 1
FOUNDSOURCESCHUNKS 3

6.2 Kontextaufbau

GetContext(...) arbeitet in mehreren Stufen:

  1. Frage-Embedding erzeugen
  2. TOP CONTEXTCANDIDATES Chunks per VECTOR_COSINE suchen
  3. pro Kandidat den eigentlichen Chunk laden
  4. mit BuildSourcePreview(...) lexikalische Treffer zaehlen
  5. nur Chunks mit mindestens MINMATCHTERMS oder einem ausreichend hohen MINMATCHSCORE uebernehmen
  6. maximal MAXCHUNKSPERDOCUMENT Chunks je Dokument
  7. insgesamt maximal CONTEXTCHUNKS Chunks in strContext

6.3 Warum CONTEXTCANDIDATES = 256 wichtig ist

Bei importierten Webseiten kann der HTML-Ursprung viel Navigation, Banner und Meta-Inhalt enthalten. Dadurch kann ein inhaltlich richtiger Chunk trotz korrekt importierter Daten in der semantischen Rangliste weit hinten landen.

Ein konkreter Fall:

6.4 Antwortgenerierung

Ask(...) ruft intern:

  1. GetContext(...)
  2. GetAnswerLLM()
  3. Antwort-Normalisierung fuer Terminal und Web

Das LLM bekommt:

6.5 Fundstellen

strFoundSources speichert zusaetzliche Quellhinweise fuer die Anzeige im Terminal und im Dashboard.

Die Anzeige wird dabei bewusst strenger gefiltert als der eigentliche Kontext:

  1. Matching fuer Kontext und Fundstellen arbeitet mit normalisierten Suchtermen, sodass z. B. entwickelt und entwickelte zusammenfinden.
  2. Fundstellen werden dokumentbasiert aggregiert, nicht mehr nur aus den zuerst akzeptierten Chunks zusammengesetzt.
  3. Angezeigt werden nur Dokumente mit dem besten ermittelten Source-Score.

Damit bleiben bei Mehrbereichsabfragen die fachlich passenden Hauptquellen sichtbar, waehrend schwache Nebentreffer wie allgemeine Richtlinien- oder Story-Dokumente nicht mehr in der Fundstellenanzeige auftauchen.

7. Web-Architektur

7.1 Dispatcher

IrisRAG.Web.Dispatcher ist %CSP.REST und steuert:

Routen

Route Methoden Handler
/ GET ShowDashboard
/dashboard GET ShowDashboard
/login GET/POST ShowLogin, DoLogin
/ask POST DoAskPrompt
/logout GET DoLogout
/admin/login GET/POST ShowAdminLogin, DoAdminLogin
/admin GET ShowAdmin
/admin/save POST DoAdminSave
/admin/logout GET DoAdminLogout

7.2 Dashboard

Web.Dashboard rendert:

Dashboard – Frage und Antwort

7.3 Admin

Web.Admin rendert fünf Tabs:

  1. Benutzer
  2. Gruppen
  3. Bereiche
  4. Verlinkungen
  5. RAG-Dokumente

Der Dokumente-Tab ist die technische Verwaltungsoberflaeche fuer:

Admin – Tab Benutzer

Admin – Tab Gruppen

Admin – Tab Bereiche

Admin – Tab Verlinkungen

Admin – Tab RAG-Dokumente

7.4 Admin-POST-Aktionen

Neben Benutzer-/Gruppen-/Bereichsverwaltung sind relevant:

Action Bedeutung
import_rag_upload startet ImportUploadedDocument(...)
import_rag_url startet ImportUrlAsDocument(...)
import_rag_path startet ImportByPath(...) fuer relativen Pfad innerhalb SRCVOLUMEPATH
import_rag_abspath startet ImportByAbsolutePath(...) fuer beliebigen Originalpfad
delete_dokument loescht Dokument inkl. aller Chunks; ruft Dispatcher.DeleteDokument(id) auf

7.5 Login-Seiten

Seite Klasse Route
Benutzer-Login Web.Login /login
Admin-Login Web.AdminLogin /admin/login

Benutzer-Login

Admin-Login

8. Session- und Sicherheitslogik

Der Dispatcher trennt zwei Login-Welten:

Session-Key Bedeutung
LoggedIn regulaerer Web-Benutzer
UserName eingeloggter Benutzer
SelectedBereiche aktuell ausgewaehlte Suchbereiche
AdminLoggedIn Admin-Status
AdminLastDetail technische Detailmeldung fuer Admin-Fehlerbanner

OnPreDispatch(...) entscheidet:

9. Betrieb mit Container und Ollama

9.1 IRIS im Container

Die Anwendung laeuft im Container iris-orb. Entwicklung und Troubleshooting erfolgen typischerweise ueber:

docker exec -it iris-orb iris session iris

Namespace:

zn "USER"

9.2 Klassen nachladen

Beispiel:

set sc = $system.OBJ.Load("/tmp/LLMProxy.cls", "ck")

ck bedeutet Laden und Kompilieren.

9.3 Ollama

Es werden zwei Endpunkte genutzt:

Zweck Endpunkt
Embeddings http://host.docker.internal:11434/api/embeddings
Chat http://host.docker.internal:11434/api/chat

10. Entwickler- und Diagnosewege

10.1 Embedding-Check

write ##class(IrisRAG.RAGDokumente).%New().GetOllamaEmbeddingInfo()
set sc = ##class(IrisRAG.RAGDokumente).%New().CheckOllamaEmbeddingConfig()

10.2 RAG-Benchmarks

w ##class(IrisRAG.LLMProxyEntwicklerTests).BenchmarkAsk("hat ralf kenntnisse in ML?", 1, 3)
w ##class(IrisRAG.LLMProxyEntwicklerTests).BenchmarkContextOnly("was findest du zu Observability with OpenTelemetry", 1, 5, "DEFAULT")
w ##class(IrisRAG.LLMProxyEntwicklerTests).BenchmarkContextOnlyWithoutEmbedding("hat ralf kenntnisse in ML?", 5, 5)

10.3 Typische Fehlerbilder

Symptom Ursache Behebung
Webseite konnte nicht importiert werden. Importpfad nicht beschreibbar oder HTTP-Fehler Detailmeldung im Admin pruefen
Keine Information im Kontext gefunden. relevanter Chunk liegt ausserhalb des Candidate-Fensters oder Bereich falsch gewaehlt Bereich pruefen, Candidate-Fenster pruefen
keine Fundstellen Kontext leer oder Source-Filter verwirft alle Kandidaten Importinhalt sowie MINMATCHTERMS und MINSOURCESCORE pruefen

11. Aktueller Technologiestand

Die aktuelle Anwendung umfasst jetzt vollstaendig: