Semantisches Such-Backend hinter der vorhandenen Registry-Grenze, statt Retrieval in wikitool einzubauen #35
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Aus der Plattform-Debatte vom 2026-09-01. Der Bedarf: hybrides Retrieval (BM25 + Vektor,
semantische Suche) für einen Korpus in der Größenordnung wenige Tausend Seiten, weil
ripgrepallein dort nicht mehr trägt.Die Naht existiert bereits
tools/chemenu/search/registry.pysagt es im eigenen Docstring:Dazu
search/base.py(Backend-Protokoll, „a backend answers the text half of a query andnothing else"),
search/fuse.py(Reciprocal Rank Fusion — ausdrücklich gebaut, um lexikalischeund semantische Rankings ohne gemeinsame Score-Skala zu kombinieren) und
search/ripgrep.py(betreibt seit Tag eins einen fremdsprachigen Prozess hinter dieser Grenze). Das gesamte
Suchmodul sind 613 Zeilen.
Frontmatter-Prädikate bleiben in
filters.pyund laufen nachgelagert — ein Vektor-Backend mussconfidence>=0.8nie kennen.Größenordnung: kein ANN-Index nötig
Überschlag für 5.000 Seiten bei ~250-Token-Chunks: grob 20.000–25.000 Chunks, bei 768 Dimensionen
float32 rund 77 MB. Ein linearer Kosinus-Scan darüber liegt im niedrigen zweistelligen
Millisekundenbereich — gegenüber 50–400 ms für das Einbetten der Query selbst.
Ein ANN-Index (HNSW o. ä.) spart also einen Bruchteil eines Vorgangs, der von etwas anderem
dominiert wird, und handelt sich Rekall-Verlust und Indexpflege ein. Brute Force reicht bei
dieser Größenordnung. Das erledigt den größten Teil der Bibliotheksdiskussion, bevor sie
beginnt.
qmdprüfen, bevor etwas nachgebaut wirdkb/entities/tools/qmd.mdbeschreibt genau das gesuchte Profil. Verifiziert am 2026-09-01 gegenhttps://github.com/tobi/qmd: qmd ist TypeScript/Bun und löst die Aufgabe über SQLite FTS5 +
sqlite-vec + node-llama-cpp mit GGUF-Modellen (embeddinggemma-300M, Qwen3-Reranker). Es bringt
einen MCP-Server und HTTP-Transport auf
localhost:8181mit.Damit ist „einhängen statt nachbauen" keine Architekturskizze, sondern eine Konfigurationsfrage.
Zu prüfen, bevor entschieden wird:
kollidiert mit dem Determinismus-Anspruch dieses Stacks (
AGENTS.md, „never re-derive, alwayscompile") und macht dieselbe Anfrage zweimal verschieden beantwortbar.
kb/richten lässt, ohne Annahmen über unser Frontmatter zu treffenDie Alternative — ein eigenes Backend in Python — ist bei Brute-Force-Kosinus überschaubar
(NumPy-Dot-Produkt über eine Matrix) und hat den Vorteil, keine Fremdabhängigkeit zu erben. Der
Nachteil ist, dass Embedding-Erzeugung, Chunking und Modellverwaltung dann selbst gebaut werden.
Was der Preis der Grenze ist, ehrlich
Modellwechsel bedeutet Vollreindex. Das ist echte, nicht wegdefinierbare Versionsdrift.
Wissenskompiler ist das das schlechtere Fehlerbild. Braucht einen
doctor-Check:Index-Zeitstempel gegen jüngstes
modified:im Korpus.rgkostet 7 ms; ein Embedding-Prozess kostet Hunderte ms bis Sekunden proStart. Das verlangt einen residenten Prozess — den #19 ohnehin mitbringt.
dist exportunddoctormüssen sie als optional führen.Präzedenzfall existiert:
RipgrepMissinginsearch/ripgrep.py.Offene Fragen
API? Das entscheidet über Offline-Fähigkeit, Latenz und laufende Kosten.
##-Abschnitteneine natürliche Struktur, die ein Chunker nutzen könnte.
reports/) oder ausgeliefert?durch
fuse.py.Akzeptanzkriterien
qmdeinhängen vs. eigenes Backend, mit den Prüfpunkten oben belegtBACKENDS(search/registry.py) erreichbar,--backendwählt esrgüber RRF funktioniert; Frontmatter-Prädikate greifen unverändertwikitoolwie bei fehlendemrg: klare Meldung, kein stiller Fallbackdoctormeldet Index-Alter gegen den KorpusAuslöser für
prio/3: ein Korpus, an demrgtatsächlich nicht mehr trägt. Vorher ist daseine Wette auf eine Anforderung, die noch niemand gemessen hat.
Verwandt: #19 (der residente Prozess, in dem der Index lebt), #6 (Ranking-Signale).