语义搜索服务器

一个生产级的语义搜索服务器,支持本地零成本嵌入和重排名,适用于工程文档、法律研究、医学文献等多种场景。

  • by puran-water
  • Python
  • 本地部署
  • 6 星标
  • 更新于
在 GitHub 查看 hvkshetry/knowledge-base-mcp

使用说明

语义搜索MCP服务器

A生产级 模型上下文协议(MCP) 该服务器将最先进的MCP客户端(Claude Desktop/Code/Codex CLI)置于检索和摄取的循环中。代理使用原子MCP工具进行规划——决定提取器、分块器、重链路由、HyDE重试、图跳转和元数据预算调用——而服务器则保证确定性、来源和精简索引安全性。一切都在本地开源组件上运行,因此嵌入和重新排序仍然存在 零成本 超出您的克劳德订阅。

🌟 特性

  • 零成本嵌入和重新排名:Ollama驱动的嵌入和本地TEI交叉编码器使每个文档和查询免于每令牌费用。
  • 结构感知摄入:文档化在一次调用中处理整个PDF,性能提高约60-65%,提取表格、图表、带bbox的标题、部分面包屑和元素ID。完整文档处理消除了每页开销,同时保留了所有语义结构。
  • 面向代理的混合检索:自动模式在密集、混合、稀疏和重新排序路线之间进行选择;当分数较低时,它返回弃权,因此MCP客户端可以决定是运行HyDE还是尝试其他查询。每个图元都保持暴露状态,以便手动覆盖。
  • 多收集支持(手动):通过添加条目将文档组织到单独的知识库中 NOMIC_KB_SCOPES;默认配置附带单个集合(daf_kb).
  • 增量和确定性摄入:智能更新检测仅重新处理更改的文档。确定性块ID允许基于自动更新的更新,而无需手动清理。
  • 图形和实体(轻量级):摄入会提取设备/化学/参数实体,并将其链接回块,以便试剂可以通过 kb.entities/kb.linkouts(完整的语义关系提取仍在路线图上。)
  • 操作工具: scripts/manage_cache.py 和 scripts/manage_collections.sh 帮助清除缓存或管理Qdrant集合;GPU旋钮(DOCLING_DEVICE, DOCLING_BATCH_SIZE)保持沉重的PDF文件流畅。
  • Canary质量保证框架: ingest.assess_quality 可以运行用户提供的金丝雀查询(config/canaries/)并在文件投入生产之前报告警告。
  • 丰富的来源追踪:每一块都承载着 plan_hash, model_version, prompt_sha,以及 client_decisions 为了实现完全的可审计性。搜索结果包括 page_numbers, section_path, element_ids, table_headers, table_units,以及 bboxes 用于精确引用和来源验证。所有元数据都保存在Qdrant矢量有效载荷和FTS数据库中。
  • MCP控制的电源: ingest.upsert, ingest.upsert_batch,以及 ingest.corpus_upsert 让代理将块工件直接推送到Qdrant+FTS,而无需离开MCP工作流。
  • 客户编排摘要和HyDE:法学硕士客户通过以下方式提供部分摘要 ingest.generate_summary 并在重新查询之前在本地生成上下文感知的HyDE假设 kb.dense,每一个决定都记录在计划出处中。
  • 可观察性和护栏:搜索日志包括哈希主题ID、阶段级时间和热门搜索结果; eval.py 运行具有CI门控召回/nDCG/延迟阈值的黄金集。
  • MCP集成:与Claude Desktop、Claude Code、Codex CLI和任何符合MCP的客户端无缝协作。
  • MCP最佳实践:所有31个工具都包括标准化注释(readOnlyHint, destructiveHint, idempotentHint, openWorldHint)Pydantic输入验证、分页元数据和全面的文档字符串。
  • 代理播放手册:准备运行“检索”→ 评估→ Claude和其他MCP客户的“优化”工作流程记录在 CLAUDE.md 和 .codex/AGENTS.md.

实验/可选功能 例如SPLADE稀疏扩展、ColBERT延迟交互、自动摘要/大纲、HyDE查询扩展和强制金丝雀QA需要额外的服务或配置。详见下表状态。

功能状态概览

功能 状态 注释
核心密集/混合/稀疏检索 ✅ 工作 kb.search, kb.dense, kb.hybrid, kb.sparse, kb.batch
实体提取+图形链接 ✅ 工作 kb.entities, kb.linkouts, kb.graph (实体→块关系)
表检索 ✅ 工作(数据相关) 需要在摄取过程中提取表
MCP工具注释 ✅ 工作 所有31个工具都有 readOnlyHint, destructiveHint, idempotentHint, openWorldHint
Pydantic输入验证 ✅ 工作 models.py 提供具有字段约束的验证输入模型
分页元数据 ✅ 工作 搜索结果包括 count, retrieve_k, return_k, has_more
异步HTTP客户端 ✅ 工作 嵌入和重新排序器使用 httpx.AsyncClient 为了更好的并发性
Canary QA ⚠️ 需要用户配置 默认 config/canaries/*.json 是占位符;添加查询以强制执行门
文档摘要/大纲 ⚠️ 客户提供 ingest.generate_summary 存储具有出处的语义摘要;大纲仍然需要建立标题索引
HyDE重试 ⚠️ 客户端生成 没有服务器工具;在MCP客户端中起草假设,然后重新查询 kb.dense / kb.search 用它
MCP启动管道 ✅ 工作 ingest.upsert, ingest.upsert_batch, ingest.corpus_upsert
稀疏扩展 💤 计划中 --sparse-expander 钩子存在,但默认情况下没有捆绑SPLADE模型
科尔伯特后期互动 💤 计划中 需要外部ColBERT服务;禁用时 COLBERT_URL 未设置

✅ 今天工作· ⚠️ 需要额外的配置或构建步骤· 💤 计划/尚未实施

🤖 MCP第一架构

传统的RAG系统将检索隐藏在一个单一的API后面。此服务器将MCP客户端作为计划器:

  • 摄入作为一种工具链 – ingest.extract_with_strategy 在单次调用中使用Docling处理整个PDF(无每页路由); ingest.chunk_with_guidance 在枚举分块器之间切换(heading_based, procedure_block, table_row); ingest.generate_metadata 强制执行字节预算和提示哈希。每一步都会返回工件和计划哈希,以便进行可重放的摄取。
  • 作为可组合原语的检索 – kb.sparse, kb.dense, kb.hybrid, kb.rerank, kb.hint, kb.table_lookup, kb.entities, kb.linkouts, kb.batch, kb.quality,以及 kb.promote/demote。将这些与客户端编写的HyDE重试和计划器启发式一起使用,以在对话中分支、重试或融合策略。
  • 用洞察力进行自我批判 –结果表面满分向量(bm25, dense, rrf, rerank, prior, decay)以及 why 注释(匹配的别名、标题、表线索),让代理在给出答案之前对可信度进行推理。

因为Claude(或任何MCP客户端)一直处于主导地位,所以您可以在不放弃来源或安全性的情况下进行代理检索和确定性摄入。

🏗️ 建筑

┌──────────────────────────────┐
│  MCP Clients                 │
│  Claude Desktop / Code / CLI │
└────────────┬─────────────────┘
             │ MCP Protocol (stdio)
         ↓
┌────────────────────────────────────────┐
│         server.py (FastMCP)            │
│  ┌──────────────────────────────────┐  │
│  │  Search Modes:                   │  │
│  │  • Semantic (vector only)        │  │
│  │  • Rerank (vector + reranker)    │  │
│  │  • Hybrid (RRF + rerank)         │  │
│  └──────────────────────────────────┘  │
└─────┬──────────────┬────────────┬──────┘
      │              │            │
      ↓              ↓            ↓
┌──────────┐  ┌──────────┐  ┌────────────┐
│  Qdrant  │  │ SQLite   │  │  Ollama    │
│  Vector  │  │  FTS5    │  │ Embeddings │
│   DB     │  │  (BM25)  │  └────────────┘
└──────────┘  └──────────┘
      │
      ↓
┌──────────────┐
│ TEI Reranker │
│ (Hugging     │
│  Face)       │
└──────────────┘

处理流水线:

Documents → Extract (Docling full-document) → Chunk → Graph & Summaries → Embed → [Qdrant + SQLite FTS] → Planner → Search → Rerank → Self-Critique → Results

📋 用例

  • 工程文件:搜索技术手册、规范和手册(如水处理工程、化学工程)
  • 法律研究:查询判例法、合同和监管文件
  • 医学文献:搜索研究论文、临床指南和医学教科书
  • 学术研究:建立可搜索的论文和书籍库
  • 企业知识库:使内部文件和报告可搜索
  • 个人研究:组织和查询您的个人文档收藏

🚀 快速开始

先决条件

  • Docker桌面(适用于Qdrant+TEI重新登录)
  • Ollama(用于嵌入)
  • Python 3.9+
  • 可选但推荐:设置 HF_HOME 到可写文件夹(例如。, export HF_HOME="$PWD/.cache/hf")因此,当分流将页面路由到结构化提取时,Docling可以缓存布局模型。

安装

  1. 克隆存储库:
git clone https://github.com/yourusername/knowledge-base-mcp.git
cd knowledge-base-mcp
  1. 安装Ollama (如果尚未安装):

    • 访问 ollama.com 并为您的平台下载
    • 拉动嵌入模型:
    ollama pull snowflake-arctic-embed:xs
    
  2. 启动Docker服务 (Qdrant+TEI排名):

docker-compose up -d
  1. 设置Python环境:
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
  1. 配置您的MCP客户端:

为您的MCP客户端选择配置:

克劳德代码:

cp .mcp.json.example .mcp.json
# Edit .mcp.json and update the Python venv path

适用于克劳德桌面:

  • 复制 claude_desktop_config.json.example 内容:
    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
    • 视窗: %APPDATA%\Claude\claude_desktop_config.json
  • 更新路径以匹配您的系统(使用 wsl Windows上的命令)

用于Codex CLI:

  • 使用 .codex/config.toml.example 作为模板
  1. 摄取您的第一份文件:
.venv/bin/python3 ingest.py \
  --root /path/to/your/documents \
  --qdrant-collection my_docs \
  --max-chars 700 \
  --batch-size 128 \
  --parallel 1 \
  --ollama-threads 4 \
  --fts-db data/my_docs_fts.db \
  --fts-rebuild \
  --max-file-mb 100

重要CLI参数:

  • --max-file-mb 100:要处理的最大文件大小(默认值:64MB)。大型手册/教科书的费用增加。
  • --fts-db: 必须 匹配集合名称(例如。, data/my_docs_fts.db 为了 --qdrant-collection my_docs)
  • --max-chars 700:推荐的块大小,以实现重新链接器兼容性(旧默认值:1800)
  • --batch-size 128:嵌入批大小(新默认值:128,旧默认值:32)
  • --fts-rebuild:从头开始重建FTS数据库(增量更新时省略)
  • 文档超时已 移除 -所有文档都会处理完毕,无论大小
  1. 测试搜索:
python validate_search.py \
  --query "your search query" \
  --collection my_docs \
  --mode hybrid
  1. (可选)运行评估工具 (如果未达到阈值,则CI失败):
python eval.py \
  --gold eval/gold_sets/my_docs.jsonl \
  --mode auto \
  --fts-db data/my_docs_fts.db \
  --min-ndcg 0.85 --min-recall 0.80 --max-latency 3000
  1. 可选: 将金丝雀QA查询添加到 config/canaries/ 所以 ingest.assess_quality 可以强制执行通过/失败门,而不仅仅是报告警告。

看 安装.md 有关详细的设置说明。

🔍 搜索模式

语义搜索(mode="semantic")

使用密集嵌入的纯向量相似性搜索。

最适合:概念查询,即使没有精确的关键字匹配,也能找到相关内容

示例:“生物系统如何去除氮?”即使使用“硝化”或“反硝化”等术语,也会找到相关内容

重新排序搜索(mode="rerank",默认)

矢量检索,然后进行交叉编码器重新排序。

最适合:大多数用例-速度和准确性的良好平衡

示例:标准搜索,您希望比纯矢量搜索更精确

混合搜索(mode="hybrid")

使用RRF组合向量搜索+BM25词汇搜索,然后重新排序。

最适合:具有概念和特定关键字要求的复杂查询

示例:“不锈钢316L在氯化物环境中的腐蚀”受益于语义理解和精确的术语匹配

稀疏搜索(mode="sparse")

仅运行支持别名的BM25,适用于短关键字查询,或在语义路由错过确切术语时作为后备。

自动计划器(mode="auto")

违约。启发式方法在语义、混合、重新排序和稀疏路由之间进行选择。当最高分低于 ANSWERABILITY_THRESHOLD,服务器放弃并返回遥测数据,以便MCP客户端(Claude等)可以决定是否生成HyDE假设并重试 kb.dense 或 kb.sparse.

其他MCP工具

  • kb.collections –列出配置的集合块及其支持索引。
  • kb.open(collection="slug", chunk_id=...) –通过以下方式获取块 chunk_id 或 element_id,可选择按char偏移量进行切片。
  • kb.neighbors(collection="slug", chunk_id=...) –将FTS邻居拉到一个块周围以获取更多上下文。
  • kb.summary(collection="slug", topic=...) –检索在摄取过程中构建的轻量级部分摘要(RAPTOR风格)。
  • kb.graph(node_id=...) –检查轻量级图形(doc→ 部分→ 块→ 实体)从结构化元数据生成。

📊 搜索参数

参数 默认值 说明
query -- 搜索查询文本
mode rerank semantic, rerank, hybrid, sparse,或 auto
top_k 8 返回最终结果(1-100)
retrieve_k 24 初始候选人库(1–256)
return_k 8 重新排名结果(≤ retrieve_k)
n (适用于kb邻居) 10 (推荐) 上下文扩展的邻居半径-综合答案为必填项

参数调整指南

场景 retrieve_k return_k top_k 模式
快速搜索 12 8 5 重新排序
全面的 48 16 10 混合动力
高精度 24 12 5 混合动力
探索性 32 12 8 语义

配置旋钮

通过环境变量(或CLI标志(如果可用))设置:

环境变量 目的
MIX_W_BM25, MIX_W_DENSE, MIX_W_RERANK 调整词汇、密集和重新排序信号之间的混合。
HF_HOME 文档模型使用的Hugging Face缓存目录(默认 .cache/hf).
GRAPH_DB_PATH, SUMMARY_DB_PATH 覆盖轻量级图形和摘要存储位置。
ANSWERABILITY_THRESHOLD 自动模式响应所需的最低分数;较低的分数会返回弃权,让客户处理(例如,运行HyDE或重新措辞)。
上下文检索 关键:搜索后始终使用kb.nighbors(n=10) -单个块在块大小700时是不够的。

备注:文档超时已删除。所有文件无论大小都会处理完毕。

📚 用法

看 用法.md 获取全面的文件,包括:

  • 摄入参数和示例
  • 多收集设置
  • 高级搜索功能(邻居扩展、时间衰减)
  • 增量摄入模式
  • 性能调优

有关即将进行的改进,请查看 ROADMAP.md.

📘 延伸阅读

  • CLAUDE.md –Claude Desktop/Code的MCP代理提示,包括摄入和检索工作流。
  • .codex/AGENTS.md –Codex CLI的MCP代理提示。
  • ARCHITECTURE.md –深入了解RRF、重新分级和分块设计选择。
  • ROADMAP.md –计划中的功能包括SPLADE稀疏扩展和ColBERT后期交互。

🏛️ 建筑细部

看 建筑.md 深入了解:

  • 互易秩融合(RRF)算法
  • 交叉编码器重新排序策略
  • 邻居上下文扩展
  • 嵌入模型选择原理
  • 分块策略

🛠️ 配置

环境变量

所有配置都可以通过环境变量进行定制。看 .env.示例 获取完整文档。

关键变量:

  • OLLAMA_MODEL:嵌入模型(默认值: snowflake-arctic-embed:xs)
  • QDRANT_URL:Qdrant服务器(默认值: http://localhost:6333)
  • TEI_RERANK_URL:重新排序端点(默认值: http://localhost:8087)
  • HYBRID_RRF_K:RRF参数(默认值:60)
  • NEIGHBOR_CHUNKS:上下文扩展(默认值:1)

多收藏设置

使用独立的搜索工具配置多个知识库:

{
  "NOMIC_KB_SCOPES": "{
    \"technical_docs\": {
      \"collection\": \"engineering_kb\",
      \"title\": \"Engineering Documentation\"
    },
    \"legal_docs\": {
      \"collection\": \"legal_kb\",
      \"title\": \"Legal Research\"
    }
  }"
}

这将创建两个MCP工具: search_technical_docs 和 search_legal_docs.

🔧 故障排除

服务未启动?

# Check Docker services
docker-compose ps

# Check Ollama
curl http://localhost:11434/api/tags

# Check Qdrant
curl http://localhost:6333/collections

嵌入失败?

  • 确保Ollama模型已被拉出: ollama list
  • 检查Ollama是否正在运行: ollama serve (通常自动启动)
  • 尝试减少批量大小:添加 --embed-batch-size 16 接收命令

搜索未返回任何结果?

  • 验证集合名称是否与摄入匹配
  • 检查Qdrant集合是否存在: curl http://localhost:6333/collections/{collection_name}
  • 确认FTS数据库路径正确

看 常见问题.md 对于更常见的问题。

📈 演出

硬件建议:

  • 最小:4GB RAM,2个CPU内核
  • 推荐:8GB RAM,4个CPU内核
  • 最优:16GB RAM,8+CPU内核

基准测试 (近似值,因硬件而异):

  • 摄入:5-10页/秒(含Ollama嵌入物)
  • 搜索延迟:100-300ms(带重新分级的混合模式)
  • 存储:每个块约2-3KB(向量+有效载荷)

🤝 贡献

欢迎投稿!请参阅 贡献.md 作为指导方针。

📄 许可证

MIT许可证-请参阅 许可证 文件以获取详细信息。

🙏 致谢

内置:

📞 支持


为什么要进行本地嵌入和重新排序?

  • 💰 零额外成本:不收取每份文件嵌入费,不收取每次查询的重新登录费-只收取Claude订阅费
  • 📈 无限规模:无需增加成本即可摄取和搜索无限量的文档
  • ⚡ 快:本地搜索,延迟<300ms-没有嵌入或重新排序的API往返
  • 🎯 控制:完全定制嵌入模型、搜索参数和分块策略