Das RAG-System-Framework: Alles, was Sie wissen müssen
Autor: Provimedia GmbH
Veröffentlicht:
Aktualisiert:
Kategorie: KI-Tools & Workflows
Zusammenfassung: Ein privates RAG-System muss Dokumente und Code strukturiert erfassen, Quellen, Versionen und Berechtigungen berücksichtigen sowie Datenabfluss begrenzen. Bei Frameworks 2026 zählen Wartbarkeit, Auswechselbarkeit, Dokumentation und messbarer Betrieb mehr als eine lange Integrationsliste.
Anforderungen an ein privates RAG-System für Dokumente und Quellcode
Ein privates RAG-System für Dokumente und Quellcode braucht mehr als eine Suchfunktion mit Chatfenster. Es muss Inhalte zuverlässig erfassen, Zugriffsrechte beachten und Antworten auf nachvollziehbare Textstellen stützen. Besonders bei Legacy-Code zählt der genaue Zusammenhang: Dateipfad, Projekt, Version und Abhängigkeiten sind oft wichtiger als ein einzelner ähnlicher Absatz.
Die wichtigste Vorgabe lautet daher: Das System sollte Datenzugriff, Kontextaufbau und Modellaufruf klar trennen. So bleibt sichtbar, welche Informationen gespeichert werden, welche Treffer in eine Anfrage gelangen und welche Daten einen externen Dienst erreichen.
Dokumente und Quellcode getrennt behandeln
PDF-Dateien, Handbücher und Tickets bestehen meist aus längeren Textblöcken. Quellcode folgt dagegen einer festen Struktur. Eine Klasse sollte nicht mitten in einer Methode geteilt werden. Bei C# sind etwa Namespace, Klasse, Methode, XML-Kommentar und zugehörige Tests wertvolle Einheiten.
Für die Aufnahme sind deshalb unterschiedliche Regeln sinnvoll:
- Dokumente nach Überschriften, Absätzen und Seiten strukturieren
- Quellcode nach Datei, Namespace, Klasse, Methode und Kommentar zerlegen
- Imports, Signaturen und Dateipfade als Metadaten speichern
- Tests, Konfigurationen und generierten Code gesondert kennzeichnen
- Binärdateien, Geheimnisse und Build-Ausgaben vor der Aufnahme ausschließen
Ein Treffer sollte nicht nur Text liefern. Er braucht eine Herkunft, zum Beispiel src/Orders/OrderService.cs, Commit-ID, Branch und Zeilennummern. Damit kann die Anwendung den gefundenen Ausschnitt später einordnen, statt lose Codefragmente zusammenzuwerfen.
Metadaten entscheiden über die Qualität
Eine Vektorsuche erkennt semantische Ähnlichkeit. Sie kennt aber nicht automatisch die Bedeutung eines Branches oder die Gültigkeit einer Version. Metadaten schließen diese Lücke. Für Unternehmensdateien sind unter anderem Dokumenttyp, Abteilung, Erstellungsdatum, Freigabestatus und Vertraulichkeitsstufe nützlich.
Bei Quellcode kommen Sprache, Repository, Branch, Commit, Projektdatei und Abhängigkeit hinzu. Die Anwendung sollte diese Felder vor der Suche filtern können. Eine Frage zu einem aktiven Release darf nicht versehentlich Treffer aus einem alten Prototypen erhalten.
Zugriffsschutz bis zur einzelnen Anfrage
Ein privates System ist nicht automatisch sicher. Entscheidend ist, ob ein Nutzer nur Inhalte abrufen kann, für die er berechtigt ist. Die Zugriffskontrolle muss deshalb vor dem Retrieval greifen. Ein nachträgliches Entfernen aus dem Prompt reicht nicht, weil der unzulässige Treffer dann bereits verarbeitet wurde.
Praktisch bewährt sich ein Zugriffstoken pro Anfrage. Es enthält Nutzer, Rolle, Projekt und erlaubte Datenbereiche. Der Retriever nutzt diese Angaben als Filter. Zusätzlich sollten Protokolle festhalten, welche Quellen verwendet wurden, ohne den vollständigen vertraulichen Inhalt unnötig zu duplizieren.
Der Modellaufruf braucht eine klare Grenze
Wer eine externe API nutzt, sollte den ausgehenden Kontext bewusst begrenzen. Nicht jede gefundene Datei gehört in den Prompt. Sinnvoll sind Auswahlregeln für Trefferzahl, Dateigröße, Vertraulichkeitsstufe und Aktualität. Geheimnisse wie API-Schlüssel, Zertifikate oder Passwörter müssen bereits vor der Indexierung erkannt und entfernt werden.
Für besonders sensible Projekte bietet sich ein lokales Modell für Embeddings und eine lokale Vorverarbeitung an. Nur der tatsächlich benötigte Kontext wird anschließend an das Sprachmodell gesendet. Das reduziert Datenabfluss und Kosten, ersetzt aber keine Prüfung der Vertrags- und Speicherbedingungen des jeweiligen API-Anbieters.
C# als technische Basis
Im .NET-Umfeld sollte die Anwendung aus kleinen Diensten bestehen: Importer, Parser, Indexierer, Retriever und Chat-API. Diese Trennung erleichtert Tests und spätere Wechsel. Eine Datenbankabstraktion verhindert, dass die Geschäftslogik an einen einzelnen Vektor-Dienst gekoppelt ist.
Für den Einstieg genügt ein lokaler Dienst mit wenigen Repositories und einer klaren Quellenanzeige. Wichtig ist ein reproduzierbarer Import: Gleiche Datei und gleiche Version sollten nicht bei jedem Lauf neue Duplikate erzeugen. Hashes, Dokument-IDs und Änderungszeitpunkte helfen dabei.
Die passende Architektur liefert also nicht bloß ähnliche Textstellen. Sie muss Herkunft, Version, Berechtigung und Datenschutz gemeinsam abbilden. Genau diese Anforderungen entscheiden später stärker über den Nutzen als der Name des eingesetzten Frameworks.
Die wichtigsten Auswahlkriterien für Frameworks im Jahr 2026
Im Jahr 2026 sollte ein RAG-Framework nicht nur viele Schnittstellen anbieten. Entscheidend ist, ob es den gesamten Lebenszyklus einer Anwendung sauber unterstützt: von reproduzierbaren Experimenten über den Betrieb bis zur späteren Ablösung einzelner Komponenten. Für ein privates Coding-Projekt zählt dabei vor allem eine schlanke Architektur. Ein überladenes Framework kann sonst mehr Wartungsarbeit erzeugen als Nutzen.
Bewerte deshalb nicht die Anzahl der Integrationen, sondern die Kontrollpunkte. Wer kann Datenversionen festlegen? Lassen sich Anfragen messen? Können einzelne Bausteine ohne Umbau ersetzt werden? Genau solche Fragen trennen eine brauchbare Entwicklungsbasis von einer bloßen Demo.
Programmiersprache und Ökosystem
Die Sprachwahl beeinflusst den Aufwand stärker, als es Vergleichstabellen vermuten lassen. Python bietet im KI-Umfeld meist die größte Auswahl an Beispielen und Erweiterungen. Für ein bestehendes .NET-Projekt kann C# dennoch die bessere Wahl sein, weil Authentifizierung, Hosting, Tests und vorhandene Geschäftslogik bereits dort liegen.
Prüfe vor der Entscheidung:
- Gibt es aktuelle Pakete für die gewünschte Laufzeit, etwa .NET 8 oder .NET 9?
- Sind Beispiele für Streaming, strukturierte Antworten und Tool-Aufrufe vorhanden?
- Werden asynchrone Abläufe, Cancellation Tokens und Dependency Injection sauber unterstützt?
- Wie schnell erscheinen Updates nach Änderungen an Modell- oder API-Schnittstellen?
Ein Framework mit hervorragender Python-Dokumentation ist nicht automatisch passend, wenn der produktive Dienst in C# laufen soll. Eine stabile REST- oder gRPC-Grenze kann diesen Unterschied ausgleichen. Sie bringt aber zusätzliche Bereitstellung und Fehlerquellen mit sich.
Dokumentation und Wartbarkeit
Gute Dokumentation zeigt nicht nur den ersten Import. Sie erklärt auch Fehlerfälle, Versionswechsel und Grenzen. Achte auf API-Referenzen, Migrationshinweise, Beispielprojekte und ein öffentliches Änderungsprotokoll. Veraltete Codebeispiele sind ein Warnsignal, besonders wenn sie noch alte Modellnamen oder entfernte Methoden verwenden.
Hilfreich ist ein kleiner Praxistest mit drei Aufgaben: einen eigenen Retriever anschließen, eine Antwort mit Quellenobjekten erzeugen und einen Fehler kontrolliert behandeln. Miss dabei nicht nur die Zeit bis zum ersten Ergebnis. Notiere auch, wie viele Sonderlösungen nötig sind und ob die Abstraktionen verständlich bleiben.
Auswechselbarkeit statt Lock-in
Ein RAG-System besteht aus mehreren Schichten. Das Framework sollte diese Schichten nicht untrennbar vermischen. Ein Modellwechsel darf beispielsweise nicht erfordern, dass Parser, Promptvorlagen und HTTP-Clients neu geschrieben werden.
- Modelladapter: einheitlicher Zugriff auf Chat-, Embedding- und Bewertungsmodelle
- Speicheradapter: klarer Vertrag für Suche, Filter und Löschung
- Promptschicht: versionierte Vorlagen außerhalb des Quellcodes
- Ausgabeschicht: strukturierte Ergebnisse statt schwer prüfbarer Freitexte
Besonders wertvoll sind kleine, stabile Schnittstellen. Sie wirken unspektakulär, sparen später aber viel Zeit. Framework-Magie, die intern mehrere Schritte versteckt, beschleunigt den Start und erschwert oft die Fehlersuche.
Messbarkeit im laufenden Betrieb
Ein RAG-Framework sollte jede Antwort technisch nachvollziehbar machen. Dazu gehören Laufzeit, Tokenverbrauch, Fehlerrate, Suchparameter und verwendete Dokument-IDs. Der eigentliche Inhalt muss dabei nicht zwangsläufig vollständig im Log landen.
Für die Qualität sind getrennte Messwerte sinnvoll:
- Trefferquote: Wird die relevante Quelle gefunden?
- Kontexttreue: Stützt sich die Antwort auf gefundene Inhalte?
- Antwortqualität: Ist die Lösung fachlich brauchbar?
- Latenz: Wie lange dauert Suche plus Modellaufruf?
- Kosten: Wie viele Tokens und Rechenressourcen benötigt eine Anfrage?
Lege dafür einen kleinen Testsatz mit echten Fragen an. Eine gute Antwort auf zehn typische Fälle ist aussagekräftiger als eine hohe Zahl an GitHub-Sternen. Wiederhole den Test nach jeder Änderung an Parsern, Prompts oder Modellparametern.
Produktionsreife und Betrieb
Für 2026 gehören Wiederholungslogik, Timeouts, Begrenzung paralleler Anfragen und saubere Fehlerzustände zum Mindestumfang. Ein Modellanbieter kann langsam reagieren oder vorübergehend nicht verfügbar sein. Das Framework sollte solche Fälle nicht als unverständliche Ausnahme bis in die Benutzeroberfläche durchreichen.
Ebenso wichtig sind Hintergrundaufgaben für Indexaktualisierungen, Gesundheitsprüfungen und kontrollierte Löschvorgänge. Bei privaten Anwendungen genügt oft ein einzelner Dienst. Plane trotzdem klare Zustände für Import, Verarbeitung, Fehler und erneuten Versuch ein.
Die beste Wahl ist damit selten das umfangreichste Paket. Sie fällt auf die Lösung, die dein Team versteht, messen kann und bei Bedarf ohne großen Umbau austauscht. Für ein C#-Projekt sollte ein kurzer Prototyp mit realen Dateien und echten Fragen die Entscheidung bestimmen, nicht die glänzendste Funktionsliste.
Vergleich zentraler Frameworks und Komponenten für RAG-Systeme
| Framework oder Komponente | Stärken | Geeignet für | Zu beachten |
|---|---|---|---|
| LangChain | Flexible Pipelines, Werkzeuganbindung, Streaming und komplexe Abläufe | Coding-Assistenten mit Such-, Test- und Agentenfunktionen | Hohe Abstraktionstiefe und teilweise schnelle Änderungen im Ökosystem |
| LlamaIndex | Starke Datenaufnahme, strukturierte Knoten, Quellenbeziehungen und Query Engines | Wissensbasen mit Dokumenten-, Code- und Versionsbeziehungen | Das Kernökosystem ist Python-zentriert; C# benötigt häufig eine zusätzliche Schnittstelle |
| Dify | Visuelle Workflows, schnelle Prototypen und integrierte API-Bereitstellung | Interne Wissens-Chats und Anwendungen mit geringer Entwicklungszeit | Weniger geeignet für tiefgreifende Codeanalyse und vollständig individuelle Retrieval-Logik |
| Haystack | Explizite Pipelines und klar getrennte Verarbeitungsschritte | Kontrollierte Such- und Generierungsabläufe | Für einfache Projekte kann der Aufbau umfangreicher als nötig sein |
| Qdrant | Vektorsuche mit leistungsfähigen Metadatenfiltern | Private RAG-Systeme mit Projekt-, Branch- und Versionsfiltern | Benötigt eine separate Suchdienst-Installation und Pflege |
| Milvus | Skalierbare Verarbeitung großer Vektormengen | Große Repositories und hohe Abfrageraten | Für ein kleines Nebenprojekt möglicherweise überdimensioniert |
| Firecrawl | Bereinigung und Strukturierung von Webinhalten, einschließlich dynamischer Seiten | Aufnahme technischer Online-Dokumentation in eine Wissensbasis | Ersetzt keine Zugriffskontrolle, Quellenverwaltung oder fachliche Prüfung |
LangChain: Flexible Pipelines mit hoher technischer Kontrolle
LangChain eignet sich vor allem dann, wenn der Ablauf einer RAG-Anwendung nicht in einer fertigen Vorlage stecken soll. Jede Stufe lässt sich als eigener Baustein modellieren: Eingabe prüfen, Anfrage umformen, mehrere Suchwege ausführen, Treffer bewerten und anschließend eine Antwort erzeugen. Das ist mächtig, aber nicht automatisch bequem.
Für ein Coding-System ist besonders die Trennung zwischen normalem Ablauf und Agentenlogik nützlich. Ein fester Ablauf bleibt vorhersehbar. Ein Agent kann dagegen Werkzeuge wählen, etwa eine Repository-Suche, einen Compiler oder einen Testlauf. Diese beiden Modi sollten nicht vermischt werden: Freie Werkzeugwahl erhöht den Funktionsumfang, macht Ergebnisse aber schwerer reproduzierbar.
Die aktuelle Architektur von LangChain teilt viele Aufgaben in spezialisierte Pakete. Für Python sind unter anderem langchain-core, langchain-community und Anbieterpakete üblich. Diese Aufteilung wirkt zunächst kleinteilig. Sie reduziert jedoch unnötige Abhängigkeiten und macht sichtbarer, welche Komponenten eine Anwendung tatsächlich verwendet.
Ein wichtiger Baustein ist LangGraph. Es beschreibt mehrstufige Abläufe als Zustandsgraphen. Ein Knoten kann beispielsweise eine Suchanfrage erzeugen, ein weiterer die Treffer prüfen und ein dritter eine Antwort formulieren. Übergänge lassen sich an Bedingungen knüpfen. So kann der Ablauf bei fehlendem Kontext eine zweite Suche starten, statt sofort eine unsichere Antwort zu liefern.
Für die Entwicklung mit C# ist die offizielle .NET-Unterstützung weniger geschlossen als das Python-Ökosystem. Eine praktikable Lösung ist deshalb oft, LangChain nur als Referenz für Konzepte zu verwenden und die benötigten Schritte direkt in .NET nachzubauen. Für eine Claude-Anbindung genügt technisch ein typisierter HTTP-Client. Wer die Bibliothek dennoch einsetzen möchte, sollte die Pflege des jeweiligen .NET-Ports getrennt von der Python-Dokumentation bewerten.
LangChain bringt außerdem ein nützliches Muster für Nachrichten und Ausgaben mit. Antworten können als strukturierte Daten angefordert werden, etwa als JSON mit Dateien, Symbolen und Änderungsvorschlägen. Das ist für Coding-Anwendungen deutlich belastbarer als ein langer Freitext, der erst nachträglich zerlegt werden muss.
- Ausdrucksstarke Abläufe: Bedingungen, Schleifen und parallele Schritte lassen sich gezielt kombinieren.
- Werkzeuganbindung: Repository-Suche, Testausführung oder statische Analyse können als klar definierte Funktionen dienen.
- Streaming: Zwischenergebnisse lassen sich schrittweise an die Oberfläche übertragen.
- Erweiterbarkeit: Eigene Komponenten können über standardisierte Schnittstellen eingebunden werden.
Die größte Schwäche liegt in der Abstraktionstiefe. Ein scheinbar kleiner Aufruf kann mehrere interne Operationen auslösen. Bei Fehlern muss man daher wissen, welcher Runnable-Schritt, welches Nachrichtenformat oder welcher Callback beteiligt war. Wer LangChain nutzt, sollte die Kette zunächst bewusst kurz halten und jeden Übergabewert protokollieren.
Auch die Versionsentwicklung verlangt Aufmerksamkeit. Paketnamen, Integrationen und empfohlene Muster ändern sich schneller als bei klassischen .NET-Bibliotheken. Fixierte Versionen, automatisierte Integrationstests und ein kleines eigenes Adaptermodul verhindern, dass ein Update die gesamte Anwendung berührt.
Für das beschriebene Projekt ist LangChain daher kein Selbstzweck. Es passt, wenn komplexe Abläufe, Werkzeuge und spätere Agentenfunktionen geplant sind. Für eine einfache Frage-Antwort-Suche kann eine direkte .NET-Implementierung schlanker sein. Der entscheidende Test lautet: Bleibt der Ablauf auch dann verständlich, wenn eine Suche fehlschlägt oder der Codebestand widersprüchliche Treffer liefert?
LlamaIndex: Datenaufnahme und Retrieval für wissensbasierte Anwendungen
LlamaIndex legt den Schwerpunkt auf den Weg von Rohdaten zu nutzbarem Kontext. Die Bibliothek stellt dafür Datenobjekte, Indizes und Abfragekomponenten bereit. Im Vergleich zu einem allgemeinen Workflow-Toolkit wirkt dieser Ansatz besonders passend, wenn der Datenbestand selbst im Mittelpunkt der Anwendung steht.
Ein zentraler Baustein ist das Document- beziehungsweise Node-Modell. Ein Dokument kann in kleinere Knoten zerlegt werden, ohne dass Herkunft und Zusatzinformationen verloren gehen. Beziehungen zwischen Knoten erlauben außerdem mehr als eine flache Ähnlichkeitssuche. So lassen sich etwa Abschnitte, Seiten, Überschriften oder zusammengehörige Codeeinheiten miteinander verknüpfen.
Für große Repositories ist diese Struktur hilfreich. Eine Methode kann mit ihrer Klasse, der Datei und einer übergeordneten Dokumentation verbunden werden. Bei einer Abfrage lässt sich zunächst der passende Knoten finden. Danach kann die Anwendung ergänzende Nachbarn oder übergeordnete Einheiten nachladen. Das reduziert isolierte Codefragmente und verbessert den Kontext, ohne jedes Mal komplette Dateien zu übertragen.
LlamaIndex unterstützt mehrere Indexarten. Ein Vektorindex eignet sich für semantische Ähnlichkeit. Ein Listen- oder Baumindex bildet dagegen andere Abfragemuster ab, etwa Zusammenfassungen über mehrere Dokumente. Graphbasierte Ansätze können Beziehungen zwischen Entitäten und Quellen abbilden. Diese Auswahl ist kein Selbstzweck: Die Indexform sollte zur Fragestellung passen.
Interessant für technische Wissensbestände sind die sogenannten Query Engines und Chat Engines. Eine Query Engine beantwortet einzelne Fragen auf Basis eines Indexes. Eine Chat Engine hält dagegen Gesprächskontext und kann Folgefragen verarbeiten. Für ein Coding-Werkzeug sollte dieser Verlauf begrenzt und gezielt aktualisiert werden, sonst vermischen sich alte Annahmen mit dem aktuellen Codezustand.
- Retriever: sucht passende Knoten aus einem Index.
- Node Postprocessor: filtert, ordnet oder bewertet gefundene Inhalte.
- Response Synthesizer: erstellt aus den ausgewählten Knoten eine Antwort.
- Query Pipeline: verbindet mehrere Verarbeitungsschritte mit klaren Ein- und Ausgaben.
Ein weiterer Vorteil ist die Möglichkeit, mehrere Datenquellen als getrennte Indizes zu behandeln. Handbücher, Quellcode und Fehlertickets müssen dann nicht in einem gemeinsamen Suchraum liegen. Eine Anfrage kann zunächst den passenden Bereich bestimmen und anschließend nur dort suchen. Das verringert zufällige Treffer aus fachfremden Quellen.
Für hybride Suche lässt sich eine semantische Abfrage mit exakten Begriffen verbinden. Das ist bei Fehlermeldungen, Klassennamen und Versionsnummern besonders nützlich. Ein reines Embedding findet ähnliche Formulierungen, übersieht aber unter Umständen den exakten Bezeichner. Die Kombination aus Volltext- und Vektorsuche ist hier oft die robustere Variante.
Wer LlamaIndex mit C# einsetzen möchte, sollte die Sprachfrage früh klären. Das Kernökosystem ist Python-zentriert. Eine .NET-Anwendung kann den Dienst über HTTP ansprechen oder die benötigten Daten- und Abfragekonzepte direkt nachbilden. Für ein kleines Projekt ist die zweite Variante manchmal überschaubarer als eine zusätzliche Laufzeit. Sie erfordert allerdings eigene Pflege für Import, Knotenmodell und Abfrageabläufe.
LlamaIndex passt damit besonders zu Anwendungen, die Quellen strukturiert erfassen und über mehrere Ebenen abfragen müssen. Seine Stärke liegt weniger in maximaler Agentenfreiheit als in der Modellierung von Wissen. Für ein privates Codearchiv ist das interessant, wenn Beziehungen zwischen Datei, Symbol, Dokumentation und Änderungshistorie einen echten Mehrwert liefern.
Dify: Visuelle Entwicklung mit integrierter RAG-Pipeline
Dify richtet sich an Teams, die eine RAG-Anwendung über eine Oberfläche zusammenstellen und anschließend als Dienst bereitstellen möchten. Statt jeden Verarbeitungsschritt selbst zu programmieren, werden Datenquellen, Wissensbasis, Prompt, Modell und Antwortverhalten in einer Anwendung verbunden.
Der praktische Vorteil liegt im schnellen Änderungszyklus. Ein Prompt lässt sich anpassen, eine Wissensbasis neu verarbeiten oder ein anderes Modell testen, ohne den gesamten Anwendungscode zu verändern. Für interne Prototypen und klar abgegrenzte Frage-Antwort-Szenarien ist das angenehm unkompliziert.
Dify trennt dabei mehrere Bausteine, die in der Oberfläche separat verwaltet werden:
- Wissensbasis: enthält importierte Dateien und die zugehörige Suchkonfiguration.
- Anwendung: definiert Chatverhalten, Eingaben und Ausgaben.
- Workflow: bildet mehrstufige Abläufe mit Bedingungen und Aktionen ab.
- Modellkonfiguration: verbindet die Anwendung mit einem Sprach- oder Embedding-Modell.
- API-Zugang: macht die erstellte Anwendung für andere Oberflächen oder Dienste nutzbar.
Für Entwicklerteams ist die Trennung von Wissensbasis und Anwendung besonders praktisch. Mehrere Anwendungen können auf denselben Bestand zugreifen, etwa ein allgemeiner Dokumenten-Chat und ein zweiter Assistent für technische Fragen. Änderungen an der Benutzeroberfläche müssen dadurch nicht zwingend die Datenaufnahme beeinflussen.
Die visuelle Workflow-Ansicht eignet sich für nachvollziehbare Prozesse. Ein Ablauf kann etwa eine Frage klassifizieren, eine Wissensbasis auswählen, eine Antwort erzeugen und bei fehlendem Kontext eine Rückfrage stellen. Solche Schritte sind für Nicht-Programmierer leichter zu prüfen als tief verschachtelter Anwendungscode.
Für Quellcode gibt es jedoch Grenzen. Eine einfache Dateiablage genügt nicht für symbolische Beziehungen, Abhängigkeiten oder versionsabhängige Fragen. Dify kann als Bedien- und Bereitstellungsschicht dienen, während ein eigener Dienst die Repository-Analyse übernimmt. Dieser Dienst liefert anschließend gezielt aufbereitete Inhalte an den Workflow.
Bei einer selbst gehosteten Installation bleiben Infrastruktur und Konfiguration unter eigener Kontrolle. Das allein garantiert noch keinen sicheren Betrieb. Aktualisierungen, Backups, Netzwerkregeln, Schlüsselverwaltung und Benutzerrechte gehören weiterhin zur Aufgabe des Betreibers. Gerade die API-Schlüssel sollten nicht in exportierten Workflows oder öffentlich erreichbaren Frontend-Dateien landen.
Die Dify-API ist für eine eigene C#-Oberfläche interessant. Die Anwendung kann Anfragen per HTTP senden, Antworten streamen und die Benutzeroberfläche unabhängig vom Dify-Frontend gestalten. Vor dem produktiven Einsatz sollten jedoch Antwortformat, Fehlercodes, Limits und die Behandlung langer Gespräche geprüft werden.
Stärken und Grenzen lassen sich knapp gegenüberstellen:
- Stark: schneller Aufbau, sichtbare Abläufe, einfache Modellwechsel und fertige API-Anbindung.
- Weniger passend: tiefgreifende Codeanalyse, ungewöhnliche Retrieval-Logik und vollständig individuell getestete Datenpfade.
- Sinnvoll als Ergänzung: internes Portal, Prototyp oder Bedienebene über eigenen Import- und Suchdiensten.
Dify ist damit vor allem eine produktive Anwendungsschicht. Wer möglichst schnell einen nutzbaren Assistenten bereitstellen möchte, findet hier einen kurzen Weg. Für ein anspruchsvolles Codeverständnis sollte die Plattform aber nicht als vollständiger Ersatz für Repository-Parser, Symbolsuche und eigene Prüfprozesse betrachtet werden.
Weitere Open-Source-Frameworks für unterschiedliche RAG-Anforderungen
Die Auswahl endet nicht bei den beiden bekanntesten Bibliotheken. Je nach Ziel können spezialisierte Open-Source-Projekte besser passen. Manche konzentrieren sich auf schnelle semantische Suche, andere auf Datenpipelines, Wissensgraphen oder den Betrieb in abgeschotteten Umgebungen. Für ein privates Coding-Projekt lohnt sich deshalb ein Blick auf die jeweilige Kernaufgabe.
Haystack eignet sich für klar modellierte Such- und Generierungsabläufe. Komponenten werden zu Pipelines verbunden, die Eingaben und Ausgaben explizit beschreiben. Das erleichtert die Prüfung einzelner Schritte und passt gut zu Anwendungen, in denen Suchlogik, Dokumentenverarbeitung und Antworterzeugung getrennt getestet werden sollen.
Ragas ist kein vollständiges Anwendungsframework, sondern ein Werkzeug für die Bewertung von RAG-Ergebnissen. Es untersucht unter anderem, ob gefundener Kontext zur Frage passt und ob eine Antwort durch diesen Kontext gestützt wird. Damit kann ein Entwickler Änderungen an Prompts oder Suchparametern mit einem festen Fragensatz vergleichen.
Vespa verbindet Suchmaschine, Vektorsuche und Ranking in einer verteilten Plattform. Die Stärke liegt in der Kombination aus mehreren Signalen: Textübereinstimmung, semantische Nähe, Geschäftsregeln und eigene Bewertungsmodelle können gemeinsam in das Ranking einfließen. Für ein kleines Nebenprojekt ist der Betriebsaufwand allerdings höher als bei einer eingebetteten Bibliothek.
Milvus ist auf große Vektormengen und verteilte Suche ausgelegt. Die Architektur bietet sich an, wenn viele Embeddings, mehrere Indizes oder wachsende Abfrageraten erwartet werden. Für ein einzelnes privates Repository kann eine leichtere Lösung genügen; bei umfangreichen Datenbeständen wird die Skalierbarkeit interessanter.
Qdrant verbindet Vektorsuche mit Filtern über strukturierte Nutzdaten. Das ist nützlich, wenn Treffer nach Projekt, Sprache, Quelle oder Aktualität eingeschränkt werden sollen. Die Metadatenfilter können dabei direkt in die Suche einfließen, statt erst nachträglich große Ergebnismengen auszusortieren.
Weaviate bietet eine API-orientierte Datenplattform mit Vektorsuche, Filtern und verschiedenen Integrationsmöglichkeiten. Sie passt zu Anwendungen, die mehrere Datentypen über ein gemeinsames Schema verwalten möchten. Vor der Nutzung sollte geprüft werden, welche Module tatsächlich benötigt werden und welche davon zusätzliche Dienste voraussetzen.
Für ein C#-Projekt sind außerdem cloudunabhängige Datenbanken mit stabiler HTTP- oder gRPC-Schnittstelle interessant. Dadurch bleibt der Anwendungscode in .NET, während der Suchdienst separat betrieben wird. Das ist kein vollständiger Ersatz für eine RAG-Bibliothek, kann aber die Sprachgrenze zwischen Datenhaltung und Anwendung sauber ziehen.
- Haystack: explizite Pipelines für kontrollierte Suchabläufe
- Ragas: Messung von Retrieval- und Antwortqualität
- Vespa: komplexes Ranking mit mehreren Suchsignalen
- Milvus: große Vektormengen und verteilte Suche
- Qdrant: Vektorsuche mit präzisen Metadatenfiltern
- Weaviate: API-zentrierte Verwaltung verschiedener Wissensobjekte
Diese Projekte sind nicht austauschbar. Ein Bewertungswerkzeug ersetzt keine Datenbank, eine Suchplattform ersetzt keine Benutzeroberfläche und ein Vektordienst liefert noch keinen sicheren Dialogablauf. Die sinnvollste Kombination entsteht, wenn jede Komponente eine klar abgegrenzte Aufgabe übernimmt.
Für einen ersten Vergleich genügt ein kleiner Belastungstest mit demselben Dokumentbestand. Messe Importdauer, Suchlatenz, Filterverhalten, Speicherbedarf und Aufwand für Updates. Gerade bei Quellcode zeigt sich schnell, ob ein System exakte Bezeichner, kurze Dateien und viele kleine Einheiten zuverlässig verarbeitet. Das Ergebnis ist meist aussagekräftiger als eine allgemeine Rangliste.
Firecrawl: Webdaten sammeln und für RAG aufbereiten
Firecrawl ist kein RAG-Framework im engeren Sinn. Der Dienst übernimmt die vorgelagerte Aufgabe, Webinhalte für eine spätere Suche nutzbar zu machen. Das ist vor allem bei technischer Dokumentation hilfreich, deren HTML-Struktur, Navigation und JavaScript-Inhalte für einfache Parser oft ein ziemliches Durcheinander ergeben.
Statt rohe Webseiten zu speichern, kann Firecrawl Inhalte in bereinigtes Markdown umwandeln. Menüs, wiederholte Navigationselemente und viele Layout-Reste fallen dabei weg. Überschriften, Listen, Tabellen und Codeblöcke bleiben als verwertbare Struktur erhalten. Für die spätere Verarbeitung ist das ein wichtiger Unterschied: Ein sauberer Abschnitt lässt sich sinnvoller teilen als ein ungefilterter HTML-Mitschnitt.
Über eine Crawl-Anfrage lässt sich eine gesamte Dokumentationsseite erfassen. Einzelne URLs können dagegen gezielt mit einer Scrape-Anfrage verarbeitet werden. Für regelmäßig aktualisierte Handbücher bietet sich ein zeitgesteuerter Lauf an. Dabei sollten unveränderte Seiten anhand ihrer Kennung oder eines Inhalts-Hashes übersprungen werden. So sinken Laufzeit und Verbrauch.
Bei dynamischen Seiten ist die Ausführung von JavaScript ein praktischer Vorteil. Inhalte, die erst nach dem Laden erscheinen, gelangen dadurch ebenfalls in die Extraktion. Das löst jedoch nicht jedes Problem. Zugriffsbeschränkungen, Captchas, persönliche Konten und Inhalte hinter Bezahlschranken dürfen nicht einfach umgangen werden.
Vor der Indexierung braucht der Export eine eigene Bereinigung. Entferne beispielsweise:
- Cookie-Hinweise und Navigationsfragmente
- identische Kopf- und Fußzeilen
- Tracking-Parameter in Links
- veraltete Sprachvarianten
- automatisch erzeugte Seiten ohne fachlichen Inhalt
Ergänze anschließend Metadaten wie Quell-URL, Seitentitel, Versionsnummer, Sprache, Crawl-Zeitpunkt und kanonische Adresse. Bei Softwarehandbüchern ist die Dokumentationsversion besonders wichtig. Eine aktuelle API-Referenz und eine Anleitung für eine ältere Bibliotheksversion können sich sonst widersprechen, obwohl beide formal zur Suchanfrage passen.
Die Funktion für llms.txt kann eine kompakte Übersicht wichtiger Seiten liefern. Sie ersetzt keine fachliche Auswahl und ist auch kein Beweis für die Qualität der Quelle. Sinnvoll ist sie als Startpunkt, wenn eine Dokumentationsseite viele Unterbereiche besitzt und zunächst relevante URLs gesammelt werden sollen.
Für strukturierte Angaben bietet Firecrawl außerdem eine KI-gestützte Extraktion. Dabei wird ein Schema vorgegeben, etwa mit Feldern für Produktname, Versionsnummer und Installationsbefehl. Diese Methode eignet sich für klar abgegrenzte Datensätze. Bei unvorhersehbaren Seiten sollte das Ergebnis immer gegen das Ausgangsdokument geprüft werden, weil fehlende Angaben sonst wie gültige Nullwerte aussehen können.
Ein schlanker Ablauf sieht so aus:
- Startseiten und erlaubte Pfade festlegen
- Webinhalte abrufen und als Markdown speichern
- Duplikate sowie Navigation entfernen
- Version, URL und Abrufzeit als Metadaten ergänzen
- Änderungen erkennen und nur neue Inhalte weitergeben
- Fehlerhafte oder unvollständige Exporte in eine Prüfwarteschlange legen
Für sensible Projekte ist außerdem die Herkunft des Webinhalts relevant. Speichere neben dem Text auch die Abrufzeit und den Status der Quelle. Ein späterer Vergleich kann dann zeigen, ob eine Antwort auf einer inzwischen geänderten Seite beruht. Firecrawl beschleunigt die Sammlung, ersetzt aber weder Quellenverwaltung noch Freigabeprozess.
Im Zusammenspiel mit einem RAG-System bleibt die Rollenverteilung klar: Firecrawl beschafft und normalisiert Webdaten; der nachgelagerte Dienst übernimmt Speicherung, Suche und Antworterzeugung. Diese Trennung macht den Import austauschbar und verhindert, dass ein Webcrawler unbemerkt zum Kern der gesamten Anwendung wird.
Vektordatenbanken, Embeddings und Chunking richtig planen
Die drei Bausteine greifen unmittelbar ineinander: Embeddings machen Inhalte mathematisch vergleichbar, Chunking bestimmt die Granularität der Einträge und die Vektordatenbank organisiert Suche sowie Filter. Eine gute Framework-Wahl kann diese Grundlagen nicht ersetzen. Werden sie falsch geplant, findet selbst ein leistungsfähiges System den entscheidenden Abschnitt nicht.
Embeddings sind keine allgemeine Bedeutungskarte. Ein Modell bildet Text in Zahlen ab. Ähnliche Formulierungen liegen dabei oft nahe beieinander. Exakte Symbole, Versionsnummern oder seltene Fehlermeldungen können jedoch besser über eine zusätzliche Volltextsuche gefunden werden. Für Quellcode ist eine Kombination aus semantischer und lexikalischer Suche deshalb meist sinnvoller als ein reiner Vektorindex.
Wähle das Embedding-Modell nach Sprache, Inhalt und Betriebsort. Ein Modell, das vor allem englische Fließtexte verarbeitet, muss bei deutschem Quellcode oder gemischten Kommentaren nicht gleich gut arbeiten. Vergleiche vor der Festlegung mindestens drei Werte:
- Trefferqualität bei echten Fragen aus dem eigenen Bestand
- Speicherbedarf und Erzeugungsgeschwindigkeit
- Unterstützung für lokale Verarbeitung und die benötigte Vektordimension
Die Vektordimension beeinflusst Speicher und Indexgröße. Ein Modell mit 1.536 Dimensionen benötigt deutlich mehr Platz als eines mit 384 Dimensionen. Größer bedeutet aber nicht automatisch besser. Ein kleiner Testsatz mit zehn bis 30 realen Fragen zeigt meist schnell, welches Modell relevante Passagen zuverlässig nach oben bringt.
Beim Chunking sollte die logische Struktur Vorrang vor einer starren Zeichenzahl haben. Für Handbücher sind Überschriften, Absätze und Listen gute Grenzen. Bei Quellcode passen Klassen, Methoden und zusammengehörige Kommentare besser. Ein Chunk mit 300 bis 800 Token kann ein brauchbarer Startpunkt sein, doch die optimale Größe hängt von Dateityp und Fragestellung ab.
Zu kleine Abschnitte verlieren Zusammenhänge. Zu große Abschnitte enthalten viel Nebentext und verbrauchen das Kontextfenster. Ein moderater Überlapp von etwa 10 bis 20 Prozent kann Übergänge sichern, darf aber nicht zu zahlreichen Duplikaten führen. Bei Code ist ein syntaktischer Parser meist wertvoller als ein blindes Abschneiden nach Zeichen.
Speichere pro Chunk nicht nur den Inhalt. Nützlich sind außerdem:
- stabile Dokument- und Chunk-ID
- Start- und Endzeile oder Seitenbereich
- Dateipfad, Sprache und Repository
- Symbolname sowie übergeordnete Klasse oder Namespace
- Version, Branch und Änderungszeitpunkt
Diese Felder ermöglichen präzise Filter und eine verlässliche Darstellung der Fundstelle. Sie sollten nicht vollständig in den eingebetteten Text gepackt werden. Strukturierte Werte gehören als Metadaten in die Datenbank; der eigentliche Chunk bleibt dadurch semantisch sauber.
Bei der Datenbankauswahl zählt neben der Suchgeschwindigkeit die Qualität der Filter. Unterstützt der Dienst numerische Vergleiche, Listen, logische Bedingungen und Volltext? Lassen sich alte Einträge gezielt löschen? Gibt es Snapshots, Verschlüsselung und eine lokale Bereitstellung? Für ein privates Repository sind diese Fragen oft wichtiger als ein beeindruckender Benchmark.
Ein robuster Suchablauf kann mehrere Stufen nutzen. Zuerst werden Kandidaten semantisch und per Schlüsselwort ermittelt. Danach sortiert ein Reranker die kleine Ergebnismenge neu. Anschließend werden nahe Duplikate entfernt. So gelangt nicht fünfmal derselbe Absatz in den Kontext, nur weil er in mehreren Seitenvarianten vorkommt.
Auch die Abfrage selbst verdient Aufmerksamkeit. Eine Nutzerfrage wie „Warum ist der Auftrag langsam?“ kann mehrere Suchanfragen auslösen: nach dem Begriff, nach betroffenen Symbolen und nach bekannten Fehlermeldungen. Diese Zerlegung verbessert die Abdeckung, erhöht aber Rechenzeit und Kosten. Sie sollte daher nur bei komplexen Fragen aktiv werden.
Teste das System mit einem festen Datensatz und protokolliere verfehlte Treffer. Prüfe dabei getrennt, ob der richtige Chunk nicht gefunden wurde oder ob das Modell den gefundenen Inhalt falsch verwendet hat. Erst diese Trennung zeigt, ob Chunking, Embedding, Ranking oder Antwortlogik geändert werden muss.
Claude-API, C und Coding-Anwendungen sicher verbinden
Die Claude-API lässt sich in eine C#-Anwendung am saubersten als eigene Modellschicht einbauen. Der Rest des Systems spricht dann nicht direkt mit dem Anbieter, sondern mit einer internen Schnittstelle wie IChatModel. Sie kann Nachrichten, Werkzeuge, Streaming und Abbruchsignale abbilden. Später bleibt dadurch ein Modellwechsel möglich, ohne Such- oder Benutzerlogik umzubauen.
Für Anthropic-Anfragen gehören Modellkennung, maximale Ausgabelänge, Temperatur und Nachrichteninhalt in den HTTP-Request. Die API-Version sollte über einen zentralen Client gesetzt werden. Nutze in .NET HttpClientFactory, Zeitüberschreitungen und eine begrenzte Wiederholungslogik. Wiederhole jedoch keine Anfrage, wenn unklar ist, ob der Server sie bereits verarbeitet hat.
Ein sicherer C#-Client sollte mindestens folgende Aufgaben übernehmen:
- API-Schlüssel ausschließlich aus einem Secret Store oder Umgebungsvariablen laden
- Schlüssel niemals in Quelltext, Logs oder Fehlermeldungen schreiben
- Antworten auf Statuscode, JSON-Struktur und Nutzlastgröße prüfen
- Streaming sauber beenden, wenn der Benutzer die Anfrage abbricht
- Rate-Limit- und Serverfehler mit verständlichen Zuständen melden
Für Coding-Aufgaben sollte der Prompt nicht einfach den gesamten Suchtreffer als freien Text anhängen. Besser ist ein festes Eingabeformat mit Abschnitten für Aufgabe, Einschränkungen, relevante Dateien und erwartete Ausgabe. Jede Quelle erhält eine kurze Kennung. So kann das Modell Änderungen gezielt auf Dateien und Symbole beziehen.
Besonders nützlich sind strukturierte Antworten. Fordere beispielsweise ein Objekt mit summary, changes, tests und uncertainties an. Ein Änderungsvorschlag enthält dann Dateipfad, Startzeile, Endzeile und Patch. Die Anwendung kann diesen Vorschlag anzeigen, aber nicht automatisch ausführen.
Werkzeuge sollten mit minimalen Rechten arbeiten. Ein Suchwerkzeug darf Dateien lesen, ein Testwerkzeug darf einen isolierten Prozess starten. Schreibzugriff, Netzwerkzugriff und Shell-Befehle gehören in getrennte Freigabestufen. Besonders riskante Befehle wie Paketinstallation, Löschung oder Datenbankmigration brauchen eine ausdrückliche Bestätigung.
Für Vorschläge an Legacy-Code empfiehlt sich ein dreistufiger Ablauf:
- Das Modell beschreibt die vermutete Ursache und nennt die verwendeten Quellen.
- Es erzeugt einen begrenzten Patch statt einer vollständigen Datei.
- Die Anwendung führt Formatprüfung, Build und Tests in einer abgeschotteten Umgebung aus.
Die Testumgebung sollte ein eigenes Arbeitsverzeichnis, begrenzte CPU- und Speicherressourcen sowie deaktivierten oder streng gefilterten Netzwerkzugriff besitzen. Ein Patch darf erst nach erfolgreicher Prüfung in den Arbeitsbestand übernommen werden. So wird aus einer sprachlichen Empfehlung kein unkontrollierter Eingriff in das Repository.
Behandle Gesprächsverläufe außerdem nicht als dauerhafte Wahrheit. Eine frühere Modellantwort kann veraltet oder schlicht falsch sein. Speichere besser die konkrete Aufgabe, den Patch, das Prüfergebnis und die verwendete Revision. Für eine neue Anfrage wird der benötigte Verlauf gezielt zusammengestellt.
Die API-Anbindung ist zudem eine Kostenfrage. Begrenze Eingabelänge und Ausgabelänge, entferne doppelte Ausschnitte und beende unnötige Agentenschleifen. Eine einfache Zählung von Tokens, Laufzeit und Fehlern pro Vorgang zeigt schnell, welche Funktionen den größten Verbrauch verursachen.
Datenschutz: Sensiblen Legacy-Code unter eigener Kontrolle halten
Datenschutz bei einem privaten RAG-System entsteht nicht allein durch den Betrieb auf eigener Hardware. Entscheidend ist die gesamte Datenkette: vom Quellcode-Checkout über temporäre Dateien und Embeddings bis zur Antwortausgabe. Auch ein scheinbar harmloser Dateiname, Stack Trace oder Kommentar kann interne Informationen enthalten.
Lege zuerst eine Datenklassifizierung fest. Trenne etwa öffentliche Inhalte, interne Dokumente, vertraulichen Quellcode und besonders geschützte Informationen. Diese Klassen bestimmen, welche Verarbeitung erlaubt ist, wie lange Daten gespeichert werden und ob ein externer Modellaufruf überhaupt infrage kommt.
- Öffentliche Inhalte dürfen meist in einer getrennten Wissensbasis liegen.
- Interne Dokumente brauchen definierte Nutzer- und Prozessregeln.
- Vertraulicher Legacy-Code sollte nur nach ausdrücklicher Freigabe verarbeitet werden.
- Geheimnisse, Zugangsdaten und private Schlüssel gehören niemals in den Index.
Ein häufiger Irrtum betrifft Embeddings. Sie enthalten nicht den ursprünglichen Text, sind aber auch keine anonymen Werte ohne Risiko. Mit Zusatzwissen können Inhalte unter Umständen eingeordnet oder rekonstruiert werden. Behandle Embeddings daher wie abgeleitete vertrauliche Daten und schütze sie mit denselben Grundregeln wie den Quellbestand.
Für die Speicherung eignen sich verschlüsselte Datenträger, getrennte Datenbanken und klar begrenzte Dienstkonten. Nutze für Entwicklung, Test und Produktion unterschiedliche Schlüssel. Backups müssen ebenfalls verschlüsselt sein. Prüfe außerdem, ob temporäre Uploads, Container-Volumes und Suchindizes nach einer Löschung tatsächlich verschwinden.
Besonders wichtig ist die Löschbarkeit. Wenn ein Repository entfernt wird, müssen Originaldateien, extrahierte Abschnitte, Embeddings, Cache-Einträge und Suchprotokolle berücksichtigt werden. Eine feste Datenherkunft pro Eintrag erleichtert diesen Vorgang. Ohne sie bleibt eine Löschanfrage schnell unvollständig.
Bei externen Modell-APIs müssen mehrere Fragen schriftlich geklärt werden:
- Werden Eingaben und Ausgaben zum Training verwendet?
- Wie lange bleiben Anfragen und Diagnosedaten gespeichert?
- In welcher Region werden sie verarbeitet?
- Welche Unterauftragnehmer sind beteiligt?
- Gibt es Vereinbarungen zur Auftragsverarbeitung?
- Kann die Organisation die Aufbewahrung begrenzen oder abschalten?
Eine lokale Embedding-Erzeugung reduziert den ausgehenden Datenfluss, schützt aber nicht automatisch vor Fehlern in der Anwendung. Auch Debugging-Dienste, Telemetrie und externe Fehlerberichte können sensible Ausschnitte enthalten. Deaktiviere solche Übertragungen gezielt oder maskiere Inhalte vor dem Versand.
Ein weiterer Risikopunkt ist Prompt-Injection. Ein Dokument kann Anweisungen enthalten, die das Modell zum Ignorieren seiner eigentlichen Aufgabe oder zur Herausgabe zusätzlicher Daten bewegen sollen. Markiere abgerufene Inhalte daher als untrusted data. Werkzeuge dürfen Anweisungen aus Dokumenten nicht ungeprüft als Systemregeln übernehmen.
Für Legacy-Code sollte die Anwendung außerdem zwischen Lesen, Vorschlagen und Ändern unterscheiden. Eine Antwort darf Informationen liefern, ein Patch darf nur in einen separaten Arbeitsbereich geschrieben werden. Der produktive Branch bleibt geschützt. Jede Übernahme braucht eine nachvollziehbare Freigabe durch eine berechtigte Person.
Datenschutz wird zudem durch organisatorische Regeln geprägt. Lege fest, wer den Index betreibt, wer Quellen hinzufügen darf und wie Sicherheitsvorfälle gemeldet werden. Führe ein Verzeichnis der Verarbeitung, eine Risikoanalyse und regelmäßige Zugriffskontrollen. Bei personenbezogenen Daten können nach der Datenschutz-Grundverordnung zusätzliche Pflichten gelten; eine juristische Prüfung ist bei realen Unternehmensdaten sinnvoll.
Auch der EU AI Act kann je nach Einsatzbereich relevant sein. Die Einstufung hängt nicht allein vom verwendeten Modell ab, sondern vom konkreten Zweck und vom Umfeld der Anwendung. Dokumentiere daher Zweck, Nutzerkreis, menschliche Kontrolle und technische Grenzen. Für einen privaten Prototyp gelten andere Anforderungen als für ein Werkzeug, das Entscheidungen im Unternehmen beeinflusst.
Ein belastbares Schutzkonzept verfolgt damit nicht das Ziel, jedes Risiko wegzuzaubern. Es begrenzt Datenflüsse, Rechte und Auswirkungen so, dass ein einzelner Fehler nicht gleich den gesamten Codebestand preisgibt. Genau diese Begrenzung macht eine selbst betriebene Coding-Anwendung tatsächlich kontrollierbarer.
Entscheidungshilfe: Welches Framework passt zu welchem Projekt?
Die passende Wahl hängt weniger vom Etikett „RAG-Framework“ ab als vom geplanten Betriebsmodell. Ein privater C#-Assistent für Legacy-Code braucht andere Prioritäten als ein visueller Wissens-Chat für ein Team. Entscheidend ist deshalb, welches Problem gelöst werden soll und welche Teile langfristig selbst gepflegt werden können.
Für das beschriebene Nebenprojekt ist eine schlanke Eigenarchitektur meist der beste Start: C#-Anwendung, eigener Importdienst, eine Vektordatenbank, ein klarer Modelladapter und eine getrennte Oberfläche. Ein Framework sollte nur dort eingesetzt werden, wo es nachweislich Entwicklungszeit spart. Nicht jede Funktion muss aus einer großen Plattform kommen.
Die folgende Zuordnung hilft bei der Vorauswahl:
- Individuelle Coding-Anwendung: LangChain oder eine eigene .NET-Pipeline, wenn Werkzeuge, Prüfungen und Sonderlogik wichtig sind.
- Stark datenorientierte Wissensbasis: LlamaIndex, wenn Beziehungen zwischen Dokumenten, Abschnitten und Quellen im Mittelpunkt stehen.
- Schneller interner Prototyp: Dify, wenn eine Oberfläche und ein nutzbarer Workflow ohne viel Anwendungscode gefragt sind.
- Streng kontrollierte Suchpipeline: Haystack, wenn Komponenten und Übergaben möglichst explizit bleiben sollen.
- Große Suchinfrastruktur: Milvus, Vespa oder Weaviate, wenn Datenmenge, Abfragerate und komplexes Ranking den Ausschlag geben.
- Qualitätsmessung: Ragas als Ergänzung, nicht als Ersatz für eine vollständige Anwendung.
Für den konkreten C#-Fall spricht wenig dafür, Python nur wegen eines bekannten Namens zum Kern der Lösung zu machen. Eine zusätzliche Laufzeit kann sinnvoll sein, wenn bereits fertige Komponenten benötigt werden. Sie erzeugt aber einen weiteren Dienst, eine weitere Bereitstellung und eine weitere Stelle für Fehler. Prüfe deshalb zuerst, ob die benötigte Funktion über eine stabile HTTP-Schnittstelle oder mit wenigen eigenen Klassen abbildbar ist.
LangChain ist die bessere Wahl, wenn aus dem Assistenten später ein Werkzeug mit mehreren Aktionen werden soll. Dazu gehören etwa Repository-Suche, Testausführung, Patch-Erstellung und ein Freigabeschritt. LlamaIndex ist stärker, wenn die Qualität der Datenstruktur und die Navigation durch Quellen wichtiger sind als freie Agentenabläufe.
Dify passt vor allem dann, wenn die Anwendung schnell von mehreren Personen ausprobiert werden soll. Für ein persönliches Codewerkzeug kann es jedoch zu viel Oberfläche und zu wenig Kontrolle über die fachliche Codeanalyse bieten. Ein eigener Dienst bleibt in diesem Szenario oft leichter auf die tatsächlichen Aufgaben zugeschnitten.
Die Entscheidung sollte durch einen Vergleich mit demselben Testsatz fallen. Verwende fünf bis zehn typische Fragen aus dem eigenen Projekt und prüfe:
- Wie viel Code ist nötig, bis die erste brauchbare Antwort entsteht?
- Wie einfach lassen sich eigene Such- und Prüfschritte ergänzen?
- Kann die Anwendung Fehler und Abbrüche verständlich behandeln?
- Wie gut bleibt der Ablauf nach sechs Monaten noch lesbar?
- Wie leicht lässt sich eine Komponente später ersetzen?
Bewerte außerdem den Wechselaufwand. Wenn ein Framework den gesamten Datenbestand in eigene Objekte überführt, Prompts intern speichert und Modellaufrufe stark kapselt, kann ein späterer Ausstieg mühsam werden. Offene Datenformate, exportierbare Metadaten und eigene Tests senken dieses Risiko.
Meine Empfehlung für das beschriebene Projekt lautet daher: Beginne mit einer kleinen C#-Pipeline ohne Agenten. Ergänze zunächst Repository-Abfrage, Quellenanzeige und Patch-Vorschläge. Erst wenn dieser Kern stabil funktioniert, lohnt sich die Entscheidung für komplexere Workflow- oder Agentenfunktionen. Für maximale Erweiterbarkeit kommt LangChain als Konzept oder Dienstschicht infrage; für eine datenorientierte Python-Komponente ist LlamaIndex die naheliegende Alternative.
Das „beste“ Framework ist somit kein allgemeiner Sieger. Es ist das Werkzeug, das den gewünschten Ablauf mit möglichst wenigen versteckten Abhängigkeiten abbildet. Beim privaten Legacy-Code zählt am Ende nicht die längste Integrationsliste, sondern ein kleiner, verständlicher und kontrollierbarer Systemkern.
Fazit: Mit einer kleinen, getesteten Pipeline starten
Die beste Entscheidung für ein privates RAG-Projekt ist selten ein möglichst großes Gesamtpaket. Beginne mit einem klar begrenzten Ziel: eine Frage, ein definierter Datenbestand und eine Antwort mit überprüfbaren Quellen. Erst wenn dieser Kern zuverlässig arbeitet, zeigen sich die Anforderungen für weitere Bausteine.
Für das geplante C#-Projekt empfiehlt sich ein kleiner Referenzaufbau. Halte eine feste Sammlung typischer Fragen bereit und speichere neben jeder Frage die erwartete Quelle oder das erwartete Ergebnis. So entsteht ein Vergleichspunkt für neue Modelle, Datenimporte und Suchverfahren. Ohne solche Referenzen wirkt eine Verbesserung schnell nur subjektiv.
Bewerte jede Änderung mit denselben Messgrößen:
- Wurde die relevante Information gefunden?
- Ist die Antwort durch die gefundene Quelle gedeckt?
- Bleibt die Antwort bei fehlendem Wissen zurückhaltend?
- Wie lange dauert die Verarbeitung?
- Wie hoch sind Rechenaufwand und API-Kosten?
Starte zunächst ohne autonome Agenten und ohne automatische Codeänderungen. Ein deterministischer Ablauf liefert eine bessere technische Vergleichsbasis. Danach können Werkzeuge wie Testausführung, Patch-Erstellung oder mehrstufige Recherche einzeln ergänzt werden. Jede Erweiterung sollte einen konkreten Nutzen zeigen und über einen eigenen Testfall verfügen.
Für die Framework-Wahl ergibt sich daraus eine pragmatische Reihenfolge: Eine eigene .NET-Pipeline passt, wenn C# und geringe Abhängigkeiten im Vordergrund stehen. LangChain ist interessant für komplexe Werkzeugabläufe. LlamaIndex bietet sich an, wenn die Struktur der Wissensbestände den Kern bildet. Dify eignet sich für einen schnellen visuellen Anwendungstest. Kein Ansatz ist grundsätzlich überlegen.
Plane außerdem einen klaren Ausstiegspfad. Exportierbare Dokumente, stabile Kennungen und versionierte Konfigurationen verhindern, dass ein späterer Wechsel zum Großumbau wird. Bewahre Prompts, Tests und Suchparameter außerhalb flüchtiger Oberflächen auf. Das klingt trocken, rettet aber oft ein Projekt, wenn sich Schnittstellen ändern.
Ein gutes erstes Ergebnis ist kein allwissender Coding-Assistent. Es ist ein kleines Werkzeug, das bei ausgewählten Fragen verlässlich hilft, seine Grenzen offen zeigt und keine unerwarteten Änderungen vornimmt. Von dort aus kann die Anwendung wachsen – Schritt für Schritt, statt alles auf einmal zu verknoten.