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 |
UserRag
-> UserGruppeRag
-> GruppeRag
-> BereichGruppeRag
-> BereichRag
RAGDokumente
-> RAGDokumenteChunks
RAGDokumente speichert Metadaten, Quellpfad, Hash, Zeitstempel und Bereich. RAGDokumenteChunks speichert Chunk-Text und Vektor-Embedding.
| Klasse | Beziehung |
|---|---|
BereichRag |
1:n zu RAGDokumente |
RAGDokumente |
children zu RAGDokumenteChunks |
UserRag / GruppeRag |
m:n ueber UserGruppeRag |
GruppeRag / BereichRag |
m:n ueber BereichGruppeRag |
| 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 |
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 |
pypdf.PdfReader extrahiertConvertHtmlToMarkdown() in Markdown-nahen Text umgewandeltpip install trafilatura)Technischer Ablauf:
Web.Admin liest die lokale Datei mit JavaScript ueber FileReader./admin/save gesendet.Web.Dispatcher.DoAdminSave() ruft ImportUploadedDocument(...) auf.Technischer Ablauf:
/admin/save.Web.Dispatcher ruft ImportUrlAsDocument(...) auf.urllib.request.DocBook.UI.Page_a3f7b291.md). Damit erzeugen URLs mit gleichem Pfad aber unterschiedlichen Query-Parametern keine Dateikollisionen.UPLOADROOTDIR/url gespeichert.ImportStagedDocument(...) fuehrt danach den regulaeren RAG-Import aus.QuelleUrl des Dokuments gespeichert.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.
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:
SRCVOLUMEPATH muss konfiguriert sein.SRCVOLUMEPATH/dateiname gesucht. Fehlt sie dort, wird ein erklaerungsfaehiger Fehler zurueckgegeben.ImportStagedDocument(...).Parameter:
SRCVOLUMEPATH = /Users/admin/IRIS_Data/src
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:
.pdf, .txt, .md, .html, .htm, .json, .xml, .csv.SRCVOLUMEPATH (/Users/admin/IRIS_Data/src/) kopiert.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.
Vor der eigentlichen Speicherung wird fuer jede Datei ein SHA256-Hash gebildet.
Die Logik lautet:
UpdateEmbeddings(...)SaveEmbeddings(...)| Parameter | Wert |
|---|---|
CHUNKSIZE |
700 |
CHUNKOVERLAP |
150 |
EMBEDDINGDIM |
768 |
OLLAMAMODEL |
nomic-embed-text |
OLLAMAURL |
http://host.docker.internal:11434/api/embeddings |
OLLAMATIMEOUT |
20 |
RAGDokumente speichert:
DateiNameVerzeichnisDateiHashEinleseZeitpunktBereichRagQuelleUrl – optionale Quell-URL; wird nur beim URL-Import befuellt, bei Datei-Upload und Verzeichnisimport leerRAGDokumenteChunks speichert:
ChunkIndexChunkTextChunkEmbedding als Vector| 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 |
| 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 |
GetContext(...) arbeitet in mehreren Stufen:
TOP CONTEXTCANDIDATES Chunks per VECTOR_COSINE suchenBuildSourcePreview(...) lexikalische Treffer zaehlenMINMATCHTERMS oder einem ausreichend hohen MINMATCHSCORE uebernehmenMAXCHUNKSPERDOCUMENT Chunks je DokumentCONTEXTCHUNKS Chunks in strContextCONTEXTCANDIDATES = 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:
Observability with OpenTelemetry lag im importierten Release-Notes-Dokument in Chunk 189CONTEXTCANDIDATES = 36 wurde er nie betrachtetCONTEXTCANDIDATES = 256 wird er in die weitere Filterlogik einbezogenAsk(...) ruft intern:
GetContext(...)GetAnswerLLM()Das LLM bekommt:
strFoundSources speichert zusaetzliche Quellhinweise fuer die Anzeige im Terminal und im Dashboard.
Die Anzeige wird dabei bewusst strenger gefiltert als der eigentliche Kontext:
entwickelt und entwickelte zusammenfinden.Damit bleiben bei Mehrbereichsabfragen die fachlich passenden Hauptquellen sichtbar, waehrend schwache Nebentreffer wie allgemeine Richtlinien- oder Story-Dokumente nicht mehr in der Fundstellenanzeige auftauchen.
IrisRAG.Web.Dispatcher ist %CSP.REST und steuert:
| 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 |
Web.Dashboard rendert:

Web.Admin rendert fünf Tabs:
Der Dokumente-Tab ist die technische Verwaltungsoberflaeche fuer:





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 |
| Seite | Klasse | Route |
|---|---|---|
| Benutzer-Login | Web.Login |
/login |
| Admin-Login | Web.AdminLogin |
/admin/login |


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:
/dashboard oder /ask angemeldet sein muss/admin/* angemeldet sein mussDie Anwendung laeuft im Container iris-orb. Entwicklung und Troubleshooting erfolgen typischerweise ueber:
docker exec -it iris-orb iris session iris
Namespace:
zn "USER"
Beispiel:
set sc = $system.OBJ.Load("/tmp/LLMProxy.cls", "ck")
ck bedeutet Laden und Kompilieren.
Es werden zwei Endpunkte genutzt:
| Zweck | Endpunkt |
|---|---|
| Embeddings | http://host.docker.internal:11434/api/embeddings |
| Chat | http://host.docker.internal:11434/api/chat |
write ##class(IrisRAG.RAGDokumente).%New().GetOllamaEmbeddingInfo()
set sc = ##class(IrisRAG.RAGDokumente).%New().CheckOllamaEmbeddingConfig()
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)
| 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 |
Die aktuelle Anwendung umfasst jetzt vollstaendig:
QuelleUrl fuer importierte WebseitenImportByPath und ImportByAbsolutePathcopy_to_rag-Hilfsprogramm (Tkinter-GUI) fuer vereinfachten Dateitransfer in Container-VolumesSRCVOLUMEPATH-Parameter fuer pfadbasierten Import