このプロジェクトについて
# QMD - Query Markup Documents
QMDは、個人のナレッジベース、ドキュメント、会議メモ、その他Markdownベースのコンテンツ向けに設計されたオンデバイス検索エンジンです。完全にローカルで動作し、BM25全文検索、ベクトル意味検索、LLMベースのリランキングを組み合わせて、データを外部サービスに送信せずに高品質な結果を提供します。
## 主な機能
- **ハイブリッド検索パイプライン**: BM25 (FTS5)、ベクトル類似度検索、LLMリランキングを組み合わせます。クエリ展開は、適切なバックエンドにルーティングされる型付きサブクエリ(キーワード用の`lex`、密ベクトル用の`vec`、仮想的なドキュメント埋め込み用の`hyde`)を生成し、Reciprocal Rank Fusion (RRF) で融合し、LLMでリランキングします。
- **コンテキストツリー**: コレクションに階層的なコンテキストを追加できます(例: `qmd://notes` → 「個人メモとアイデア」)。これは一致するドキュメントと一緒に返され、LLMがより適切なコンテキスト判断を行うのに役立ちます。
- **ローカルモデル**: HuggingFaceからダウンロードされたGGUFモデルを使用し、ローカルにキャッシュします。デフォルトの埋め込みモデルは`embeddinggemma-300M-Q8_0`(約300MB)です。カスタムモデルは`QMD_EMBED_MODEL`環境変数で設定できます(多言語コーパス用など)。
- **AST対応チャンキング**: コードファイル(TypeScript、JavaScript、Python、Go、Rust)向けのオプションのtree-sitterベースのチャンキングにより、高品質なチャンクを生成します。他のファイルタイプでは正規表現ベースのチャンキングを使用します。
- **MCPサーバー**: クエリ、ドキュメント取得、バッチ取得、ステータスチェックのためのツールを備えたModel Context Protocolサーバーを公開します。stdioおよびHTTPトランスポートをサポートし、セキュリティ機能(DNSリバインディング攻撃を防ぐオリジン/ホスト検証)を備えています。
- **SDK**: 検索、ドキュメント取得、コンテキスト管理、クエリ展開のためのメソッドを持つTypeScript/JavaScript SDKを介したプログラムによるアクセスを提供します。
## クイックスタート
```sh
# Install globally (Node or Bun)
npm install -g @tobilu/qmd
# or
bun install -g @tobilu/qmd
# Create collections
qmd collection add ~/notes --name notes
qmd collection add ~/Documents/meetings --name meetings
# Add context
qmd context add qmd://notes "Personal notes and ideas"
# Generate embeddings
qmd embed
# Search
qmd search "project timeline" # Fast keyword search
qmd vsearch "how to deploy" # Semantic search
qmd query "quarterly planning process" # Hybrid + reranking (best quality)
```
## CLIコマンド
- `qmd collection add <path> --name <name> [--mask <glob>]` — コレクションを追加します
- `qmd collection show <name>` — コレクションの詳細を表示します
- `qmd collection include/exclude <name>` — コレクションの包含/除外を切り替えます
- `qmd collection update-cmd <name> '<command>'` — 更新コマンドを設定します
- `qmd embed [--chunk-strategy auto]` — ベクトル埋め込みを生成します
- `qmd search <query> [-c <collection>] [--json] [--files] [--min-score <n>]` — キーワード検索
- `qmd vsearch <query>` — 意味検索
- `qmd query <query>` — リランキング付きハイブリッド検索
- `qmd get <path|docid>` — ドキュメントを取得します
- `qmd multi-get <glob>` — 複数のドキュメントを取得します
- `qmd mcp [--http] [--port <n>] [--host <addr>] [--daemon]` — MCPサーバーを起動します
- `qmd status` — インデックスの健全性とMCPステータスを表示します
## MCPサーバー
公開ツール:
- `query` — 型付きサブクエリ、RRF融合、オプションのリランキングによる検索
- `get` — パス、docid、または行範囲でドキュメントを取得
- `multi_get` — グロブ、カンマ区切りリスト、またはdocidによる一括取得
- `status` — インデックスの健全性とコレクション情報
HTTPトランスポート(デフォルトポート8181)が提供するもの:
- `POST /mcp` — MCP Streamable HTTP
- `POST /query`(エイリアス `/search`) — MCPプロトコルを使わない構造化検索
- `GET /health` — 生存確認
セキュリティ: ループバック以外の`Origin`ヘッダーを持つリクエストは拒否されます(403)。`Host`検証によりDNSリバインディングを防ぎます。環境変数`QMD_ALLOWED_ORIGINS`と`QMD_ALLOWED_HOSTS`で許可されるオリジン/ホストを拡張できます。
## SDKの使用法
```js
const { QmdStore } = require('@tobilu/qmd')
const store = new QmdStore({ dbPath: './qmd.db', collections: { notes: { path: '/path/to/notes' } } })
// Simple search (auto-expanded)
const results = await store.search({ query: 'authentication flow' })
// Structured query with typed sub-queries
const results2 = await store.search({
queries: [
{ type: 'vec', query: 'why do database connections time out under load' },
{ type: 'lex', query: 'connection timeout' }
],
collections: ['docs', 'notes']
})
// Disable reranking for speed
const fast = await store.search({ query: 'auth', rerank: false })
// Metadata filtering
const published = await store.search({
query: 'typescript',
filter: { key: 'topics', operator: 'all', value: ['typescript'] }
})
// Direct backend access
const bm25Results = await store.bm25Search('auth')
const vectorResults = await store.vectorSearch('auth')
// Query expansion
const expanded = await store.expandQuery('auth flow', { intent: 'user login' })
// Document retrieval
const doc = await store.get('docs/readme.md')
const body = await store.getDocumentBody('docs/readme.md', { maxLines: 100 })
// Context management
await store.addContext('docs', '/api', 'REST API reference documentation')
await store.removeContext('docs', '/api')
```
## 検索パイプラインの詳細
1. **クエリ展開**: 元のクエリ(重み付け×2)+ LLMバリエーション1つ
2. **並列取得**: 各クエリがFTSとベクトルインデックスの両方を検索
3. **上位ランクボーナス**: いずれかのリストで1位のドキュメントには+0.05、2〜3位には+0.02
4. **Top-K選択**: リランキング用に上位30件の候補を選択
5. **再ランキング**: LLMが各ドキュメントをスコアリング(logprobs信頼度によるyes/no)
スコア範囲: 0.0〜0.2は関連性が低く、値が高いほど良い一致を示します。
## モデル設定
デフォルトモデル:
- 埋め込み: `embeddinggemma-300M-Q8_0`(約300MB)
- リランキング: LLMベース(必要に応じてダウンロード)
カスタム埋め込みモデルの例:
```sh
export QMD_EMBED_MODEL="hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf"
```
注: 埋め込みモデルを変更する場合、ベクトルは相互互換性がないため、すべてのコレクションを再埋め込みする必要があります。
## 要件
- Node.jsまたはBunランタイム
- モデルと埋め込み用の十分なローカルストレージ
- オプション: より高速なLLM推論のためのGPU/VRAM(モデルはリクエスト間でVRAMにロードされたままになります)
## ライセンス
オープンソースソフトウェアです。詳細はリポジトリを参照してください。
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.