Об этом проекте
# QMD - Query Markup Documents
QMD — это локальный поисковый движок для персональных баз знаний, документации, заметок со встреч и любого контента на основе Markdown. Он работает полностью локально, сочетая полнотекстовый поиск BM25, векторный семантический поиск и реранжирование на основе LLM, что даёт высококачественные результаты без отправки данных во внешние сервисы.
## Основные возможности
- **Гибридный поисковый конвейер**: сочетает BM25 (FTS5), векторный поиск по сходству и реранжирование LLM. Расширение запроса генерирует типизированные подзапросы (`lex` для ключевых слов, `vec` для плотных векторов, `hyde` для гипотетических эмбеддингов документов), которые направляются в соответствующие бэкенды, объединяются с помощью Reciprocal Rank Fusion (RRF) и реранжируются LLM.
- **Контекстное дерево**: добавляет иерархический контекст к коллекциям (например, `qmd://notes` → «Личные заметки и идеи»), который возвращается вместе с подходящими документами, помогая LLM принимать более обоснованные контекстные решения.
- **Локальные модели**: используются GGUF-модели, загружаемые с HuggingFace и кэшируемые локально. Модель эмбеддингов по умолчанию — `embeddinggemma-300M-Q8_0` (~300 МБ). Пользовательские модели задаются через переменную окружения `QMD_EMBED_MODEL` (например, для многоязычных корпусов).
- **Чанкинг с учётом AST**: опциональный чанкинг на основе tree-sitter для файлов кода (TypeScript, JavaScript, Python, Go, Rust) даёт более качественные фрагменты; для остальных типов файлов используется чанкинг на основе регулярных выражений.
- **MCP-сервер**: предоставляет сервер Model Context Protocol с инструментами для запросов, получения документов, пакетного получения и проверки статуса. Поддерживает транспорты stdio и HTTP с функциями безопасности (проверка origin/host для защиты от DNS-rebinding атак).
- **SDK**: программный доступ через TypeScript/JavaScript SDK с методами поиска, получения документов, управления контекстом и расширения запросов.
## Быстрый старт
```sh
# Установка глобально (Node или Bun)
npm install -g @tobilu/qmd
# или
bun install -g @tobilu/qmd
# Создание коллекций
qmd collection add ~/notes --name notes
qmd collection add ~/Documents/meetings --name meetings
# Добавление контекста
qmd context add qmd://notes "Личные заметки и идеи"
# Генерация эмбеддингов
qmd embed
# Поиск
qmd search "project timeline" # Быстрый поиск по ключевым словам
qmd vsearch "how to deploy" # Семантический поиск
qmd query "quarterly planning process" # Гибридный + реранжирование (лучшее качество)
```
## Команды 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` — пакетное получение по glob, списку через запятую или docid
- `status` — состояние индекса и информация о коллекциях
HTTP-транспорт (порт по умолчанию 8181) предоставляет:
- `POST /mcp` — MCP Streamable HTTP
- `POST /query` (алиас `/search`) — структурированный поиск без протокола MCP
- `GET /health` — проверка доступности
Безопасность: запросы с заголовком `Origin`, не указывающим на loopback, отклоняются (403). Проверка `Host` предотвращает DNS rebinding. Переменные окружения `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' } } })
// Простой поиск (автоматическое расширение)
const results = await store.search({ query: 'authentication flow' })
// Структурированный запрос с типизированными подзапросами
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']
})
// Отключение реранжирования для скорости
const fast = await store.search({ query: 'auth', rerank: false })
// Фильтрация по метаданным
const published = await store.search({
query: 'typescript',
filter: { key: 'topics', operator: 'all', value: ['typescript'] }
})
// Прямой доступ к бэкенду
const bm25Results = await store.bm25Search('auth')
const vectorResults = await store.vectorSearch('auth')
// Расширение запроса
const expanded = await store.expandQuery('auth flow', { intent: 'user login' })
// Получение документа
const doc = await store.get('docs/readme.md')
const body = await store.getDocumentBody('docs/readme.md', { maxLines: 100 })
// Управление контекстом
await store.addContext('docs', '/api', 'REST API reference documentation')
await store.removeContext('docs', '/api')
```
## Детали поискового конвейера
1. **Расширение запроса**: исходный запрос (вес ×2) + 1 вариант от LLM
2. **Параллельное получение**: каждый запрос ищет и в FTS, и в векторном индексе
3. **Бонус за верхнюю позицию**: документы на 1-м месте в любом списке получают +0.05, 2–3 места — +0.02
4. **Выбор Top-K**: берутся 30 лучших кандидатов для реранжирования
5. **Реранжирование**: LLM оценивает каждый документ (да/нет с уверенностью logprobs)
Диапазоны оценок: 0.0–0.2 — низкая релевантность, более высокие значения указывают на лучшее соответствие.
## Конфигурация моделей
Модели по умолчанию:
- Эмбеддинги: `embeddinggemma-300M-Q8_0` (~300 МБ)
- Реранжирование: на основе LLM (загружается по требованию)
Пример пользовательской модели эмбеддингов:
```sh
export QMD_EMBED_MODEL="hf:Qwen/Qwen3-Embedding-0.6B-GGUF/Qwen3-Embedding-0.6B-Q8_0.gguf"
```
Примечание: при смене модели эмбеддингов требуется повторная генерация эмбеддингов всех коллекций, поскольку векторы несовместимы между моделями.
## Требования
- Среда выполнения Node.js или Bun
- Достаточно локального хранилища для моделей и эмбеддингов
- Опционально: GPU/VRAM для ускорения инференса LLM (модели остаются загруженными в VRAM между запросами)
## Лицензия
Открытое программное обеспечение. Подробности в репозитории.
Comments
0 Rating appears after 10 ratings
Sign in to join the discussion.