Skip to main content
Glama
doc-search

doc-search

Official
by SodaShikenn

doc-search — hybride Suche + RAG-Chat für Dokumentrepository

Für das interne Dokumentrepository (Glossar, Review-Kriterien, Designdokumente) gibt es eine hybride Suchmaschine aus Stichwortsuche (BM25) × Vektorsuche (semantische Suche) und darauf aufbauend einen RAG-Chat (Claude API, Modellauswahl, Streaming-Ausgabe).

Die UI orientiert sich an SodaShikenn/LLM-RAG_KBQA
(linke Seitenleiste: Modellauswahl / Wissen-Einstellungen / Chat-Verlauf; rechts: Chat + Senden / Abbrechen).

4 Verwendungsmöglichkeiten:

  1. RAG-Chat (/) — Modell wählen und Frage stellen. Suche → Antwort mit Quellenangaben als Stream

  2. Such-Explorer (/search.html) — Inkrementelle Suche, Anzeige der KW/VEC/RRF-Scores

  3. CLI — docsearch search "..."

  4. MCP-Server — als Tool in Claude Code registriert (Agentic RAG)

Einrichtung (leichtgewichtig: keine ML-Abhängigkeiten, ~30 MB)

cd doc-search
brew install uv        # 未導入の場合
uv venv --python 3.12 .venv
uv pip install -p .venv/bin/python -r requirements.txt
cp .env.example .env   # ANTHROPIC_API_KEY を記入(チャット用)

Nur wenn ein lokales Einbettungsmodell (e5 / bge-m3) verwendet wird, kommt ein schwerer ML-Stack hinzu:

uv pip install -p .venv/bin/python -r requirements-local.txt

Related MCP server: LLMDoc

Verwendung

# 1) インデックス構築
.venv/bin/python -m docsearch index sample_docs                    # 自動選択
.venv/bin/python -m docsearch index /path/to/docs --embedder voyage  # クラウド埋め込み

# 2) サーバー起動 → http://127.0.0.1:8765
.venv/bin/python -m docsearch serve --port 8765

# 3) CLI検索
.venv/bin/python -m docsearch search "解約率" --mode vector

Auch ohne API-Schlüssel lässt sich die Chat-UI mit dem Modell „Demo (offline)“ ausprobieren.

Auswahl des Einbettungsmodells (--embedder)

Name

Ort

Gewicht

Eigenschaften

voyage

Cloud

keine lokalen Abhängigkeiten

voyage-3.5. Von Anthropic empfohlener Einbettungs-Partner. Höchste Qualitätsklasse. Benötigt VOYAGE_API_KEY. Dokumenttext verlässt das System; Zustimmung erforderlich

e5

Lokal

~470MB + torch

multilingual-e5-small. Vollständig lokal, solider Standardvektorberückt für Japanisch/Englisch

e5-large

Lokal

~2.2GB + torch

Präzisere Version von e5

bge-m3

Lokal

~2.3GB + torch

Stärkstes lokales mehrsprachiges Modell. Trotzdem das Gegenteil von „leicht“, CPU-Inferenz ist ebenfalls langsam

hash

Lokal

keine Abhängigkeiten

Hash auf Zeichenebene (keine semantische Suche, Fallback-Modus)

Auswahlhinweis: Wenn du Qualität und einfaches Setup gleichermaßen willst, nimm voyage (wenn Cloud erlaubt). Muss es vollständig lokal sein, e5; für höhere Präzision bge-m3 (wenn das Gewicht akzeptabel ist). Da BM25 (lexikalische Suche) immer lokal läuft, besteht die Rolle der Einbettung nur darin, Umformulierungen aufzunehmen — und genau hier wirkt sich das Modell aus. Die Multi-Vector-/Sparse-Funktionen von bge-m3 sind in dieser Konfiguration nicht nötig.

Chat (RAG) – Funktionsweise

質問 → 検索の深さ(effort)を解決(auto は確信度シグナルで自動判断)
     → 検索実行(hard は選択モデルがクエリを言い換え → 全変種を検索して RRF 融合)
     → system プロンプトに参照資料として注入([n] path:line 付き)
     → Claude API へストリーミング要求(output_config.effort も連動)
     → data: {status|sources|delta|done|error} を SSE 配信
     → UI が逐次描画 + 「なぜこの検索をしたか」の説明 + 引用チップ。会話は localStorage

Suchtiefe (effort) – hybrid/keyword/vector verbergen

Die Nutzer müssen sich nicht für IR-Begriffe entscheiden. Gewählt wird nur, „wie gründlich gesucht werden soll“ – was tatsächlich gemacht wurde, erscheint unter der Antwort auf Japanisch (z. B. „Automatik → gründlich – keine Keyword-Übereinstimmung … Umschreibungen wurden erzeugt und tiefer gesucht“).

Effort

Verhalten

Anwendungsfall

Automatisch (auto)

Zuerst einmal sondieren, dann automatisch easy/medium/hard je nach Sicherheit

Standard. Bei Unsicherheit diese Option

Einfach (easy)

Ein hybrider Suchlauf, Top-4-Treffer. Modell-Effort ebenfalls low

Begriffe werden direkt gesucht. Am schnellsten und günstigsten

Normal (medium)

Standard-Hybridsuche, 6 Treffer

Der bisherige Standard

Gründlich (hard)

Das gewählte Modell erzeugt 3 Umformulierungen → Suche über alle Queries und RRF-Fusion, 10 Treffer. Modell-Effort ist high

Fragen, bei denen die Formulierung in den Unterlagen von deiner Abweichung abweicht (z. B. „Gehalt für die Überstunden“ → Zuschlag für Überstunden)

Signale für „auto“: Ob Keyword-Treffer vorhanden sind, wie stark die Vektorähnlichkeit ist und welche hohen Treffer beide Sucharten sind. Falls kein Umformulieren möglich ist (Demo-Modell, kein Schlüssel gesetzt), wird „hard“ automatisch auf „erhöhte Trefferzahl“ zurückgesetzt. Die reinen Suchmodi (keyword/vector/hybrid) bleiben Entwicklern in /search.html und der CLI erhalten.

  • Modelle: Claude Opus 5 (Standard) / Sonnet 5 / Haiku 4.5 / Demo (offline)

  • Opus 5 aktiviert Server-seitigen refusal fallback: Bei verweigerten Antworten aus Sicherheitsgründen wird innerhalb desselben Requests automatisch auf ein alternatives Modell zurückgegriffen

  • Generierungs-API ist das offizielle Anthropic SDK. Der Schlüssel steht in .env in ANTHROPIC_API_KEY

Einbindung in Claude Code (MCP / Agentic RAG)

.mcp.json (im Ziel-Repository oder im Home-Verzeichnis):

{
  "mcpServers": {
    "docsearch": {
      "command": "/ABSOLUTE/PATH/doc-search/.venv/bin/python",
      "args": ["-m", "docsearch.mcp_server"],
      "env": { "DOCSEARCH_INDEX": "/ABSOLUTE/PATH/doc-search/index" }
    }
  }
}

Claude Code übernimmt die Query-Pharmung → erneute Suche → Dateilesen und -verstehen → Antwort mit Quellenangabe. Daher lässt sich im Editor, unabhängig von Chat-UI, Agentic RAG umsetzen.

Ersetzen durch echte Daten (auf einem Rechner mit Zugriffsrechten)

In diesem Repository liegen nur Platzhalter (sample_docs). Realistische Daten und Links zum internen Repository werden auf einem Rechner mit Zugriff ohne Codeänderung ersetzt. Prioritätsreihenfolge:

  1. Umgebungsvariablen (Dockers Weg): in .env
    DOCSEARCH_DOCS_HOST=/path/to/real-docs (Quelle für den Container-Mount) und
    DOCSEARCH_GITHUB_BASE=https://github.example.com/org/repo/blob/main

  2. Konfigurationsdatei (lokal ausführen): cp datasource.example.json datasource.json
    und dann docs_dir / github_base / embedder editieren → docsearch index (ohne Argumente).
    datasource.json ist gitignored, ein Verweis auf das interne Repository wird nicht gepusht

  3. Platzhalter: Ohne Konfiguration wird sample_docs/ erstellt

Die Auflösungslogik ist in der Funktion get_datasource() in der Datei docsearch/datasource.py gebündelt.

Suchtreffer, Zitier-Chips und [path:line] in Antworten verweisen direkt auf die betreffende Zeile des Dokumenten-Repositories auf GitHub. Die Form blob/<SHA zum Indexzeitpunkt>/path#L<line> wird verwendet, damit die Zeilenanker auch nach der Weiterentwicklung des Repos nicht verspringen.

  • Wird beim Indizieren automatisch aus git remote des docs-Repository erkannt (auch GHE möglich)

  • Wenn Auto-Erkennung nicht möglich ist (z. B. bei Docker/Mount-Repo): DOCSEARCH_GITHUB_BASE=https://github.com/o/r/blob/main/docs in .env bei der CLI --github-base

Designpunkte der Suchmaschine

  • Japanische Stichwortsuche: CJK-Zeichen werden in Bigramme zerlegt und in SQLite FTS5 indiziert. Auf der Anfrageseite wird das Stemming durch eine Phrasensuche über die Bigramme realisiert, sodass benachbarte Treffer erkannt werden (ohne Morphologie-Analyzer)

  • RRF-Fusion: Da BM25-Scores und Kosinus-Ähnlichkeit nicht skalär vergleichbar sind, wird in der Rangfolge fusioniert

  • Brotkrümel in Chunks: Die Kopfstruktur wird am Chunk- Anfang ergänzt (im Glossar ist der Kopf das Wort selbst)

Interessante Queries zum Austesten

Query

Erwartung

消費税区分

Mit Keyword direkt den Glossar-Eintrag finden

解約率

Vektorsuche entdeckt „Churn Rate“ (Umformulierung)

仕訳の二重登録を防ぐ仕組みは? (Chat)

Antwortzitat / Hinweis auf Idempotency-Key und Idempotenz

テナント 漏えい

Sicherheitsblickwinkel auf der Mietetrennung

Deployment

Local residency (macOS / LaunchAgent)

bash deploy/install-launchd.sh    # ログイン時自動起動・クラッシュ時自動再起動
  • Logs: logs/docsearch.log / logs/docsearch.err.log

  • S che Reis entpacken / löschen: launchctl bootout gui/$(id -u)/com.sodashikenn.docsearch && rm ~/Library/LaunchAgents/com.sodashikenn.docsearch.plist

  • macOS-TCC-Hinweis: Wenn das Repository in geschütztem Ordnern wie ~/Desktop liegt, kann der per launchd gestartete Python-Prozess den Dateizugriff verweigern und so einen Endlos Start verursachen. Falls das passiert, gib Python in „Systemeinstellungen > Datenschutz & Sicherheit“ Zugriff oder verschiebe das Repository aus dem geschützten (z. B. ~/dev/).

Docker (für Austausch mit anderen Maschinen am schnellsten)

git clone https://github.com/SodaShikenn/doc-search.git && cd doc-search
cp .env.example .env               # ANTHROPIC_API_KEY を記入
docker compose up --build -d       # → http://127.0.0.1:8765

Auf einem Mac ohne Docker (falls Docker Desktop nicht verwendet werden soll):

brew install colima docker docker-compose && colima start
mkdir -p ~/.docker/cli-plugins && ln -sfn $(brew --prefix)/opt/docker-compose/bin/docker-compose ~/.docker/cli-plugins/docker-compose
  • Falls die Einbettung vollständig lokalisiert werden soll (empfohlen für M-Reihe-Mac mit ausreichend Memory): In der .env WITH_LOCAL_ML=1 und DOCSEARCH_EMBEDDER=e5 schreiben, danach docker compose up --build -d (Image ~2–3 GB, beim ersten Mal Modell-Download). Änderungen am Embedding-Modell werden beim Befehl erkannt und automatisch neu indizet.

  • Das Standard-Slim-Image (~300 MB): Vektor-Suche nutzt VOYAGE_API_KEY, falls vorhanden, sonst Hash-Fallback (Schlüsselwortsuche insgesamt voll funktionsfähig)

  • Echte Dokumente ersetzen: In docker-compose.yml ./sample_docs:/docs:ro, bei Inhalt aktualisieren und neu indizieren DOCSEARCH_REINDEX=1 docker compose up -d

  • Schlüssel werden aus der host .env injiziert (nicht ins Image gebrannt)

  • Keine Authentifizierung vorhanden. Bei externer Veröffentlichung am Standardbindings lokal belassen und einen Reverse-Proxy (mit Authentifizierung) oder VPN verwenden.

Third-party

webui/vendor/ enthält selbst gehosted Drittanbieter-Bibliotheken, unter den jeweils eigenen Lizenzen:
marked v13.0.2 (MIT) ·
DOMPurify 3.1.6 (Apache-2.0 OR MPL-2.0).
Der übrige Teil steht unter MIT (siehe LICENSE).

Einschränkungen und Erweiterungen

  • Der Index kann nur vollständig neu aufgebaut werden (eine inkrementelle ist nicht möglich).

  • Antwortenivee Verlauf liegt im Browser-localer localStorage (keine Server-Persistenz)

  • Bewertungen: Vergleich zwischen hybrid und einzelnen Modellen bzw. Einbettungsmodellen über recall@k bei Frage → korrekte Datei bieten sich an.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    MCP server for semantic search across llms.txt documentation sources, with hybrid two-stage retrieval and automatic background refresh.
    5
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for documentation search that automatically indexes web documentation sites and provides semantic, full-text, or hybrid search capabilities.
    5 npm
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server for local RAG over personal notes, PDFs, and documents, enabling plain-English querying and hybrid search with multi-hop context expansion.
    MIT