local-corporate-kb

local-corporate-kb

Local RAG knowledge base for Qwen Code, enabling document indexing and semantic search via MCP tools. Supports metadata filtering and document retrieval without external dependencies.

Category
访问服务器

README

Локальная корпоративная база знаний для Qwen Code

Это локальный MVP корпоративного RAG: документы индексируются Python-процессом, embeddings сохраняются в проверяемый файловый кэш, а при поиске целиком находятся в RAM. Qwen Code остаётся единственной генеративной моделью и получает найденные фрагменты через read-only MCP tools. MCP-сервер не формулирует финальные ответы, не исполняет shell-команды и не изменяет документы.

Проект рассчитан на Python 3.12, uv и официальный MCP Python SDK v2. Зафиксированная версия SDK указана в uv.lock; сторонний пакет fastmcp не используется.

Архитектура

Confluence export
       ↓
knowledge/*.md, *.html, *.txt
       ↓
loader + normalizer + structural chunker
       ↓
local feature hashing (по умолчанию) или локальная embedding-модель
       ↓
NumPy matrix in RAM
       ↓
MCP stdio
       ↓
Qwen Code CLI

DocumentLoader безопасно обходит только KB_KNOWLEDGE_DIR, нормализует Markdown/TXT и переводит экспортированный HTML в Markdown-подобный текст. StructuralChunker сохраняет путь заголовков, списки, таблицы и code fences. KnowledgeService координирует кэш и работает только через интерфейс KnowledgeStore; MCP-слой не знает о NumPy.

В RAM находятся документы, чанки, отображение chunk_id -> index и нормализованная NumPy-матрица [chunk_count, embedding_dimension]. Cosine similarity считается как matrix @ query_vector.

На диске в .cache/kb/ находятся только:

  • manifest.json — версии схемы, идентичность модели, chunking config и knowledge hash;
  • documents.json — нормализованные документы и metadata;
  • chunks.json — чанки без отдельной копии embedding;
  • embeddings.npy — матрица без pickle.

Это не Vector DB: нет отдельного сервиса, индекса ANN, SQL или сетевого API. Диск используется для ускорения старта, но поиск выполняется полным cosine scan по NumPy-матрице в памяти.

Первый запуск

Убедитесь, что доступен Python 3.12. Глобальный uv не нужен: setup-скрипт создаст .venv, установит uv непосредственно в него и синхронизирует базовые зависимости из lock-файла. Hugging Face, PyTorch и sentence-transformers в базовую установку не входят:

./scripts/setup-venv.sh
source ./scripts/activate-venv.sh

После активации command -v uv должен указывать на .venv/bin/uv. Скрипт удаляет действующие shell alias/function с именем uv, ставит .venv/bin первым в PATH и экспортирует UV_BIN:

command -v python
command -v uv
echo "$UV_BIN"

Полностью локальный режим по умолчанию использует hash provider и не требует модели или сети:

./scripts/dev.sh index-hash
./scripts/dev.sh search-hash

Hash provider строит локальные lexical vectors из слов и символьных триграмм. Он пригоден для полностью автономного поиска по совпадающей терминологии, но не понимает смысл и синонимы так же хорошо, как semantic embedding model.

Для качественного semantic search сначала положите заранее полученные и одобренные model files в локальный каталог. Этот проект не скачивает их. Например:

models/Qwen3-Embedding-0.6B/

После этого активируйте окружение, укажите только локальный путь и постройте индекс:

./scripts/dev.sh install-semantic
source ./scripts/activate-venv.sh
export KB_EMBEDDING_PROVIDER=sentence_transformers
export KB_EMBEDDING_MODEL="$KB_PROJECT_ROOT/models/Qwen3-Embedding-0.6B"
export KB_EMBEDDING_LOCAL_FILES_ONLY=true

./scripts/dev.sh index-semantic
./scripts/dev.sh search "Какой сервис владеет дневными лимитами?"

local_files_only=true, HF_HUB_OFFLINE=1 и TRANSFORMERS_OFFLINE=1 запрещают обращения к Hugging Face. Если model files отсутствуют, индексирование завершится понятной ошибкой без попытки скачивания. По умолчанию выбирается CUDA, затем MPS, затем CPU.

scripts/start-mcp.sh по умолчанию запускает MCP с KB_EMBEDDING_PROVIDER=hash, поэтому обычное подключение Qwen полностью offline. Для локальной semantic-модели явно передайте provider и путь в environment Qwen-конфигурации. Все runtime wrappers используют uv run --offline --no-sync: после установки они не обращаются к package registry и не меняют окружение.

CLI

uv run --offline --no-sync kb index
uv run --offline --no-sync kb index --force
uv run --offline --no-sync kb search "Как рассчитывается дневной лимит?" --top-k 5
uv run --offline --no-sync kb search "Как рассчитывается дневной лимит?" --service limits-service
uv run --offline --no-sync kb search "Как рассчитывается дневной лимит?" --document-type business_rule
uv run --offline --no-sync kb documents
uv run --offline --no-sync kb stats
uv run --offline --no-sync kb eval
uv run --offline --no-sync kb eval --top-k 5

У search, documents, stats и eval есть --json. В этом режиме stdout содержит только JSON, а логи остаются в stderr.

Если кэша нет или он несовместим, обычный поиск при KB_AUTO_INDEX=false завершится практичным сообщением Run: ./scripts/dev.sh index. Это предотвращает неожиданную сетевую активность во время MCP discovery.

Подключение к Qwen Code

Скопируйте examples/qwen-settings.example.json в .qwen/settings.json проекта и замените все /ABSOLUTE/PATH/... реальными абсолютными путями. Не рассчитывайте на раскрытие ${PROJECT_ROOT} в JSON. В command указан абсолютный путь к .venv/bin/python, а в args — запуск модуля corporate_kb.mcp.server. Поэтому Qwen не зависит от глобальных python, uv, PATH, shell activation или wrapper-скрипта.

Минимальная форма server entry:

{
  "command": "/absolute/path/to/repository/.venv/bin/python",
  "args": ["-m", "corporate_kb.mcp.server"],
  "cwd": "/absolute/path/to/repository",
  "env": {
    "PYTHONPATH": "/absolute/path/to/repository/src"
  }
}

Альтернатива через CLI (выполняйте из корня этого репозитория, подставив абсолютные пути):

qwen mcp add \
  --scope project \
  --timeout 120000 \
  --include-tools kb_search,kb_get_document,kb_list_documents,kb_stats \
  -e KB_KNOWLEDGE_DIR=/absolute/path/to/repository/knowledge \
  -e KB_CACHE_DIR=/absolute/path/to/repository/.cache/kb \
  -e KB_EMBEDDING_PROVIDER=hash \
  -e KB_EMBEDDING_LOCAL_FILES_ONLY=true \
  -e HF_HUB_OFFLINE=1 \
  -e TRANSFORMERS_OFFLINE=1 \
  -e PYTHONUNBUFFERED=1 \
  -e PYTHONNOUSERSITE=1 \
  -e PYTHONPATH=/absolute/path/to/repository/src \
  -e KB_AUTO_INDEX=false \
  local-corporate-kb \
  /absolute/path/to/repository/.venv/bin/python \
  -m corporate_kb.mcp.server

stdio — транспорт по умолчанию, поэтому --transport http здесь не нужен. Синтаксис команды сверен с официальной документацией Qwen Code, но в среде разработки этого репозитория qwen не был установлен, и команда локально не выполнялась. JSON-конфигурация также задаёт cwd, trust: false и allowlist из четырёх tools.

Проверка подключения:

qwen
/mcp

Тестовый запрос:

Используй corporate knowledge MCP.
Найди, какой сервис владеет дневными лимитами,
объясни правило и обязательно укажи использованные источники.

Сервер предоставляет только:

  • kb_search — поиск с top_k, min_score и metadata filters;
  • kb_get_document — полный нормализованный документ по document_id;
  • kb_list_documents — metadata документов без embeddings;
  • kb_stats — состояние индекса и абсолютные пути.

Ручной запуск stdio server:

KB_LOG_LEVEL=DEBUG ./.venv/bin/python -m corporate_kb.mcp.server

stdout зарезервирован для MCP-протокола; все application logs направляются в stderr.

Добавление Confluence-страницы

Экспортируйте страницу в HTML либо сохраните её как Markdown и положите внутрь knowledge/. Поддерживаются .md, .markdown, .html, .htm, .txt. Скрытые каталоги, .git, .cache, __pycache__, node_modules, бинарные и неподдерживаемые файлы игнорируются. После изменения перестройте индекс; при обычном запуске несовпадение knowledge_hash также инвалидирует кэш.

Пример front matter:

---
document_type: service
service: limits-service
domain: payments
status: current
authority: confluence
authority_priority: 80
owner: limits-team
source_id: "confluence-12345"
source_url: "https://confluence.example.com/pages/12345"
last_reviewed: "2026-07-20"
custom_field: "неизвестные поля тоже сохраняются"
---

# Limits Service

Без front matter заголовок берётся из первого H1 или имени файла, source_id — из относительного пути, status=current, authority=local_file, authority_priority=50.

Кэш и конфигурация

Пересобрать кэш:

./scripts/dev.sh index

Полностью удалить его можно командой rm -rf .cache/kb, после чего снова выполнить kb index. Запись каждого файла атомарна, а manifest.json заменяется последним. Повреждение JSON/NumPy, несовпадение схемы, модели, dimension, query instruction, chunking config или knowledge hash приводит к понятной invalidation, а не к неясной NumPy-ошибке.

Все параметры перечислены в .env.example. Основные:

  • KB_EMBEDDING_PROVIDER=sentence_transformers|hash;
  • KB_EMBEDDING_MODEL=./models/Qwen3-Embedding-0.6B — локальный каталог model files;
  • KB_EMBEDDING_LOCAL_FILES_ONLY=true — fail-closed запрет сетевой загрузки модели;
  • KB_EMBEDDING_DEVICE=auto|cpu|mps|cuda;
  • KB_EMBEDDING_DIMENSION=1024;
  • KB_CHUNK_SIZE_TOKENS=700, KB_CHUNK_HARD_MAX_TOKENS=900, KB_CHUNK_OVERLAP_TOKENS=80;
  • KB_AUTO_INDEX=false.

Относительные пути разрешаются относительно текущего project working directory; kb stats показывает итоговые абсолютные пути.

Проверки

./scripts/dev.sh lint
./scripts/dev.sh typecheck
./scripts/dev.sh test
./scripts/dev.sh check

Обычный shell-скрипт scripts/dev.sh также объединяет повседневные команды:

./scripts/dev.sh install
./scripts/dev.sh install-semantic
./scripts/dev.sh test
./scripts/dev.sh lint
./scripts/dev.sh typecheck
./scripts/dev.sh index-hash
./scripts/dev.sh search-hash
./scripts/dev.sh index
./scripts/dev.sh search
./scripts/dev.sh index-semantic
./scripts/dev.sh eval
./scripts/dev.sh serve

Тесты всегда инжектируют hash provider и не требуют интернета, Hugging Face, GPU, Qwen Code, Docker или внешней БД. MCP integration test использует официальный v2 Client напрямую с объектом MCPServer и in-memory transport — сетевой порт не поднимается.

Ограничения MVP и развитие

  • Полный brute-force cosine scan подходит для небольшой локальной базы, но не для миллионов чанков.
  • Любое изменение документа полностью перестраивает индекс; per-document incremental rebuild нет.
  • Нет Confluence REST API, OAuth, фоновой синхронизации и HTML-адаптеров под каждый вариант экспорта.
  • Нет reranker, hybrid/BM25 retrieval и отдельной оценки authority при ранжировании.
  • Точный token counter реальной модели не используется для предварительного chunking: интерфейс TokenCounter отделён, поэтому его можно подключить без связи chunker с SentenceTransformer.
  • MCP работает только через локальный stdio subprocess.

Для перехода на настоящую Vector DB нужно реализовать PostgresKnowledgeStore или QdrantKnowledgeStore с тем же контрактом KnowledgeStore, выбрать реализацию при сборке KnowledgeService и сохранить API сервиса/MCP без изменений. Следующим этапом стоит добавить инкрементальный cache manifest, batch upsert, hybrid retrieval и production evaluation corpus.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选