CogniVault Backend erklärt, Teil 3 · Wie aus einer Frage eine belegte Antwort wird
Alle Abkürzungen werden im Anhang am Ende der Seite vollständig erklärt.
Du tippst eine Frage ein. Ein paar Sekunden später bekommst du eine Antwort mit Fußnoten — genaue Angabe der Dokumente und Seiten, aus denen sie stammt. Dieser Teil geht alles durch, was dazwischen passiert.
In Teil 2 haben wir die Wissensbasis aufgebaut: jedes Dokument gechunkt, embedded und indiziert. Jetzt fangen wir an, sie zu nutzen — und hier hört CogniVault auf, nur eine Pipeline zu sein, und fängt an, spannend zu werden.
Zwei Bibliothekare, weil einer dich immer wieder hängen lässt
Stell dir eine Bibliothek vor mit einer Bibliothekarin, die alles nach Vibes ordnet. Frag sie nach “Prozeduren bei Server-Ausfall” und sie ist genial — sie versteht, was du meinst, und findet Dokumente, die das Konzept diskutieren, egal welche Wörter sie benutzen. Aber frag sie nach “Fehlercode 404B”, zuckt sie mit den Schultern und reicht dir allgemeine Netzwerk-Guides. Mit exakten Zeichenketten kann sie nichts anfangen.
Am Ende des Flurs sitzt ein zweiter Bibliothekar mit einem Zettelkasten. Er findet den genauen String “404B” sofort — aber stell ihm eine konzeptionelle Frage, die anders formuliert ist als im Quelltext, und er findet überhaupt nichts.
Das sind die zwei Hälften der Suche:
- Semantische Suche (FAISS) — deine Frage wird in einen Vektor umgewandelt (embedded), und der Index findet Chunks, deren Vektoren in die gleiche Richtung zeigen (technisch gesehen: Cosinus-Ähnlichkeit — wie gut zwei Pfeile übereinstimmen). Super für die Bedeutung, blind für exakte Identifikatoren.
- Keyword-Suche (BM25) — eine Bewertungsformel (Scoring), die Chunks belohnt, die deine exakten Wörter enthalten, gewichtet danach, wie markant diese Wörter sind. Super für Identifikatoren, blind für Synonyme.
CogniVault fragt jedes Mal beide Bibliothekare, und verschmilzt dann ihre Antworten mit Reciprocal Rank Fusion (RRF) — einer Formel, die gerankte Listen kombiniert, indem sie nur die Positionen nutzt:
score(chunk) = summe aus beiden Listen von 1 / (60 + rang)
Ein Chunk, der von einem der beiden Bibliothekare hoch gerankt wird, punktet gut; ein Chunk, den beide gut fanden, schwimmt ganz nach oben. Die Eleganz liegt darin, was fehlt: Du musst niemals die Ähnlichkeits-Scores von FAISS mit der komplett anderen Skala von BM25 abgleichen, weil Ränge (Ranks) der einzige Input sind. Die Konstante 60 stammt direkt aus dem ursprünglichen Research-Paper von 2009, und ja, sie ist auch im Code zitiert.
Ein paar Implementierungsdetails, die du kennen solltest: Beide Suchen holen absichtlich zu viel (mindestens 20 Kandidaten jeweils), damit die Fusion Material zum Arbeiten hat; sehr schwache semantische Treffer werden fallengelassen, aber ein perfekt auf Keywords passender Chunk kann durch die Fusion trotzdem noch gerettet werden; und die finale Antwort nutzt die Top-7-Chunks. Ich habe dieses ganze Setup in Hybrid Retrieval in Practice gegen eine reine Vektorsuche gebenchmarkt, falls du die Kriegsgeschichten dazu lesen willst.
Der Agent: Ein Modell, das selbst entscheidet
Hier ist der zweite Punkt, der Anfänger oft ins Straucheln bringt: Der Chat von CogniVault ist nicht einfach “Kopiere Chunks in einen Prompt, bekomme eine Antwort.” Es ist ein Agent — ein Modell, das in einer Schleife läuft, in der es sich entscheiden kann, Tools aufzurufen, deren Ergebnisse zu lesen und erst dann zu antworten.
Gebaut mit dem Strands Agents SDK, bekommt der Agent sechs Tools:
| Tool | Aufgabe |
|---|---|
search_knowledge_base | Das Kern-RAG-Tool — führt die hybride Suche von oben aus, liefert Chunks mit Quelle und Seite zurück |
list_documents | Nachschauen, was im Vault (Tresor) liegt |
analyze_document | Strukturierte Analyse eines Dokuments: Themen, Entitäten, Fakten, Zusammenfassung |
compare_documents | Beantwortung einer Frage durch den direkten Vergleich von zwei Dokumenten |
calculator | Sicheres Rechnen — der Ausdruck wird in einen Syntaxbaum (AST) geparst und nur erlaubte Operatoren werden ausgeführt. Niemals eval() |
current_time | Datum und Uhrzeit |
Es gibt hier kein fest programmiertes Routing. Das Modell liest deine Frage und entscheidet, welche Tools es aufruft, geleitet von seinem System-Prompt. Fragst du “Vergleiche die zwei Verträge hinsichtlich der Kündigungsklauseln”, greift es zum compare_documents; fragst du “Was sind 15% von 2.340”, nutzt es den Taschenrechner, anstatt Mathematik zu halluzinieren.
Zwei Sicherheitsdetails, auf die Anfänger achten sollten, weil sie den Unterschied zwischen einem Spielzeug und einem Produkt ausmachen: Für jeden Request wird ein frischer Agent gebaut (kein geteilter State, der zwischen parallelen Chats überspricht), und die Dokumentenanalyse-Tools rufen das Modell direkt auf statt über den Agenten — sonst könnte ein Agent, der ein Tool aufruft, das wiederum den Agenten aufruft, in einer Endlosschleife feststecken.
Dem Modell beim Denken zusehen
Wenn du eine Nachricht absendest, streamt die Antwort als NDJSON (Newline-Delimited JSON — jede Zeile des Streams ist ein eigenes kleines JSON-Objekt). Und das passiert in zwei Phasen:
Phase 1 — Denken. Gemmas Argumentationskette (Reasoning Chain) streamt zuerst und wird im aufklappbaren Panel über der Antwort gerendert. Es ist absichtlich so gebaut, dass es nicht zwingend klappen muss (Best-Effort): Falls es aus irgendeinem Grund fehlschlägt, kommt die Antwort trotzdem.
Phase 2 — Die Agenten-Antwort. Tools laufen, Zitate (Quellenangaben) tauchen im Quellen-Panel auf, sobald die Suche abgeschlossen ist — bevor die Antwort fertig geschrieben ist — und der Antworttext streamt herein.
(plus optionale Bilder, Dateien, Scope)"] --> P1 subgraph STREAM["POST /rag — ein NDJSON-Stream"] P1["Phase 1: Denken
Reasoning-Chunks streamen zuerst"] P1 --> P2["Phase 2: Agent
frisch pro Request, Historie wiederhergestellt"] P2 -->|"entscheidet sich aufzurufen"| T["search_knowledge_base"] T --> D["FAISS
semantisch"] T --> S["BM25
Keywords"] D --> RRF["RRF Fusion — Top 7 Chunks"] S --> RRF RRF -->|"Chunks + Quellenangaben"| P2 P2 --> OUT["Quellenangaben, dann Antworttext,
dann ein Speicher-Nutzungs-Report"] end
Jede Zeile im Stream ist typisiert: thinking, metadata (eine Quelle/Zitat), text (Antwort), memory (wie voll das Konversations-Budget ist) oder error. Das Frontend liest einfach die Zeilen und leitet sie in das richtige Panel weiter. Ich habe dieses Design zerlegt — und erklärt, warum das Denken vor den Tool-Aufrufen kommt — in Two-Phase Streaming: Showing the Model Think Before It Acts.
Ein Speicher-Budget, kein fassloses Loch
Gemmas Context Window (die Textmenge, die das Modell auf einmal betrachten kann) beträgt 128K Token, aber CogniVault lässt den Chatverlauf nicht über das komplette Fenster wuchern. Jede Chat-Session bekommt ein Budget von 48.000 Zeichen — grob 12.000 Token. Überschreitest du es, fällt das älteste Frage-Antwort-Paar leise als erstes heraus. So bleibt der Großteil des Fensters frei für das, was wirklich zählt: deine aktuelle Frage und die abgerufenen Chunks.
Zwei Resilienz-Tricks, die du für deine eigenen Projekte klauen solltest:
- Reboots überleben. In-Memory-Verlauf stirbt mit dem Prozess. Deshalb baut die erste Nachricht in einer Session nach einem Backend-Neustart ihren Verlauf aus dem Chat-Log wieder auf, den das Frontend persistiert hat. Multi-Turn-Gedächtnis überlebt Neustarts.
- Bearbeiten und neu generieren. Wenn du eine frühere Nachricht bearbeitest, wird der gespeicherte Verlauf auf genau diesen Punkt zurückgespult, bevor neu gefragt wird — das Modell vergisst buchstäblich die Zeitlinie, die jetzt nicht mehr existiert.
Scope: Die KI auf bestimmte Dokumente festnageln
Noch ein letztes Feature, und eine Lektion über kleine lokale Modelle. Du kannst einen Chat auf bestimmte Dateien oder eine Kategorie pinnen (Scope). Dieser Filter reist mit dem Request und eine zwingende Such-Anweisung wird sowohl in den System-Prompt als auch in deine eigentliche Nutzer-Nachricht injiziert.
Warum in beide? Weil kleine Modelle manchmal Anweisungen ignorieren, die nur im System-Prompt stehen — aber sie können nicht ignorieren, was direkt in der Frage steckt. Gürtel und Hosenträger. Wenn du mit 4-Milliarden-Parameter-Modellen arbeitest statt mit den größten Frontrunnern, lernst du, Anweisungen so zu platzieren, dass man sie unmöglich übersehen kann, anstatt nur zu hoffen, dass sie befolgt werden.
Fazit
Eine belegte Antwort ist das Zusammenspiel von vier Systemen: Zwei Retriever decken gegenseitig ihre blinden Flecken ab, eine Fusionsformel, die nichts weiter braucht als Ränge, ein Agent, der sich seine Tools selbst aussucht, und ein Stream, der seinen Lösungsweg offenlegt. Keines der vier ist für sich genommen exotisch — das eigentliche Produkt ist ihre Zusammenarbeit.
Anhang: Abkürzungen in diesem Post
| Abkürzung | Volle Form | Bedeutung |
|---|---|---|
| RAG | Retrieval-Augmented Generation | Hole erst relevante Passagen aus deinen eigenen Dokumenten; lass das Modell daraus antworten |
| FAISS | Facebook AI Similarity Search | Die semantische (bedeutungsbasierte) Hälfte der hybriden Suche |
| BM25 | Best Match 25 | Die Keyword-Hälfte — eine klassische Ranking-Formel aus dem Okapi Information-Retrieval-System |
| RRF | Reciprocal Rank Fusion | Vereint die beiden gerankten Listen und nutzt dafür nur den Rang jedes Chunks: score = Σ 1/(60 + rang) |
| NDJSON | Newline-Delimited JSON | Ein Stream, bei dem jede Zeile ein eigenes komplettes JSON-Objekt ist — das Format der Chat-Antwort |
| JSON | JavaScript Object Notation | Das universelle Textformat für strukturierte Daten |
| AST | Abstract Syntax Tree | Die geparste Form eines Ausdrucks — wie der Taschenrechner rechnet, ohne eval() zu nutzen |
| LLM | Large Language Model | Ein neuronales Netz, trainiert mit riesigen Textmengen, das Sprache lesen und erzeugen kann |
| SDK | Software Development Kit | Eine Bibliothek von Bausteinen — hier Strands, das die Agenten-Schleife bereitstellt |
| K (in 128K) | Kilo (Tausend) | 128K Token ≈ 128.000 Token — Gemmas Context Window |
Als Nächstes: Teil 4 · Study Tools, Fortschritt, und die Privacy-Belege — die gleiche Maschinerie, aber ausgerichtet auf das Erstellen von Quizzes, Workshops, Karteikarten und Mindmaps, plus eine Tabelle mit jedem Byte, das die App speichert und wo genau es lebt.

Ähnliches
- CogniVault Backend erklärt, Teil 1 · Das Backend kennenlernen: Drei Prozesse, vier Schichten
- CogniVault Backend erklärt, Teil 2 · Von der Datei zum durchsuchbaren Wissen
- Teil 2 · Hybrid Retrieval in der Praxis: FAISS + BM25, verschmolzen mit RRF
- CogniVault Backend erklärt, Teil 4 · Study Tools, Fortschritt und die Privacy-Belege
- Teil 1 · CogniVault Architektur: Warum Standard-RAG nicht reicht (Hybride Suche)