Skip to main content
Glama
SodaShikenn

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. CLIdocsearch 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.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

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.
    11
    MIT
  • A
    license
    Not graded
    quality
    B
    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

View all related MCP servers

Related MCP Connectors

  • MCP server for AgentDocs (agentdocs.eu): read, search, write, comment on & share Markdown docs.

  • Hosted MCP memory: save sessions/decisions once, search from Claude, Cursor, ChatGPT. EU-hosted FTS.

  • Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/SodaShikenn/doc-search'

If you have feedback or need assistance with the MCP directory API, please join our Discord server