mcpField
H
hubmesh

hubmesh

本地服务
github.com/DemigodDSK记忆与知识21 天前更新

关于 hubmesh

hubmesh 是用于现有向量数据库之上的 Python GraphRAG 检索规划库,适合构建多跳检索的 RAG 系统。它以确定性图排序和预算感知的上下文打包规划检索,查询路径不调用大模型。

主要功能

  1. 01基于图的多跳检索规划
  2. 02融合余弦相关性与 PPR 排序
  3. 03按上下文预算打包结果
  4. 04支持 Qdrant、Chroma 与内存适配器
  5. 05实体解析与路径解释

适用场景

  1. 01检索需要跨实体关联的问题
  2. 02为现有向量数据库增加图检索
  3. 03逐跳检索并排除已用文档

MCP 相关

可选的 MCP 服务通过 stdio 或 SSE 暴露语料索引、检索、实体解析、图查询和文档读取等操作工具。查询工具不调用大模型,Agent 可自行规划多跳检索。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"demigoddsk-hubmesh": {
"command": "uvx",
"args": [
"hubmesh"
]
}
}
}
启动命令uvx hubmesh

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypihubmesh0.4.2

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

hubmesh

tests Python License: MIT Release

感知中心性的 GraphRAG 检索规划器。可直接叠加在任意向量数据库之上。

hubmesh 是一个 Python 库,可基于现有向量数据库提升多跳 RAG 的质量。你无需替换现有基础设施,只需在向量数据库和大模型之间添加一个智能规划器。

这个工具解决的问题

简单的向量检索(“嵌入查询,按余弦相似度获取 top-k”)无法处理“收购 Slack 的那家公司的创始人出生在哪里?”这类多跳问题。要得出正确答案,需要沿推理路径检索实体,而不是只检索最相似的单个条目。

GraphRAG 和 HippoRAG 表明,在查询时对知识图谱运行小规模个性化 PageRank,可以显著改善多跳检索。hubmesh 在此基础上做出了两项改进:

  1. 以实体为锚点进行播种,采用多组件排序。 在 KG 模式下,PPR 的种子是从语料库图谱中解析出的查询实体(通过别名索引;如果查询中没有实体,则回退到余弦相似度最高的匹配项中的实体);在 kNN 模式下,种子则是 ANN top-k。多组件评分——余弦相关性、汇总 PPR 权重以及多锚点收敛度,经过 min-max 归一化后按 3:1:1 融合——作用于文档排序,而非种子选择。
  2. 感知预算的上下文打包。 对相关实体评分后,将其打包到大模型的上下文窗口中,并明确控制覆盖范围和冗余,而不是简单截断 top-k。

这种多组件评分模式改编自用于 SDN 拓扑优化的 NNSI 框架(Naidu et al., CCIS 2934, Springer, 2026),并在此用于检索规划。

快速开始

内存模式(测试、小型语料库)
from hubmesh import Planner
from hubmesh.adapters import InMemoryStore

embed = ...   # callable: text -> np.ndarray
docs = [...]  # list of Document or strings or dicts

store = InMemoryStore.from_documents(docs, embed=embed)
planner = Planner(store=store, embed=embed)
result = planner.retrieve(query="...", top_k=10, budget_tokens=4000)
Qdrant 适配器(生产环境)
from hubmesh import Planner
from hubmesh.adapters import QdrantStore

store = QdrantStore.from_documents(docs)                          # in-memory
store = QdrantStore.from_documents(docs, path="./qdrant_data")    # on-disk
store = QdrantStore.from_documents(docs, url="http://localhost:6333")  # remote

planner = Planner(store=store, embed=embed)
result = planner.retrieve(query="...", top_k=10)
Chroma 适配器
from hubmesh.adapters import ChromaStore

store = ChromaStore.from_documents(docs)                          # ephemeral
store = ChromaStore.from_documents(docs, persist_directory="./chroma_data")
store = ChromaStore.from_documents(docs, host="localhost", port=8000)
多跳 / KG 模式
from hubmesh.kg import build_entity_kg
import spacy

nlp = spacy.load("en_core_web_sm")
kg = build_entity_kg(docs, nlp=nlp)

planner = Planner(store=store, kg=kg, nlp=nlp, embed=embed)   # embed= needed for text queries
result = planner.retrieve(query="Where was the founder of the company that bought Slack born?",
                          top_k=10, budget_tokens=4000)

# RetrievalResult includes reasoning paths showing why each doc was returned
for path in result.reasoning:
    print(f"  score={path.score:.3f}  {' → '.join(path.node_ids)}")
LLM 提取的 KG(比 spaCy 更丰富)
from hubmesh.kg_llm import build_entity_kg_llm
from hubmesh.entity_linker import EmbeddingLinker, make_st_embedder

def llm(prompt):  # provider-agnostic — bring your own
    return your_llm_call(prompt)

kg = build_entity_kg_llm(docs, llm=llm, cache_path="kg_cache.json")

# optional: cross-document entity dedup — same Linker protocol as the spaCy path
kg = build_entity_kg_llm(docs, llm=llm, cache_path="kg_cache.json",
                         linker=EmbeddingLinker(embed=make_st_embedder()),
                         llm_identity="gpt-5-mini")   # namespaces the cache

planner = Planner(store=store, kg=kg, nlp=nlp, embed=embed)
更好的实体链接
from hubmesh.kg import build_entity_kg
from hubmesh.entity_linker import EmbeddingLinker, make_st_embedder

# Cluster surface variations: "United States" / "U.S." / "USA" → one entity
linker = EmbeddingLinker(embed=make_st_embedder(), threshold=0.82)
kg = build_entity_kg(docs, linker=linker)
迭代式多跳:让你的 Agent 来驱动
r1 = planner.retrieve(query=question, top_k=5)

# your agent reads r1, spots the bridge entity, then aims hop 2 at it:
r2 = planner.retrieve(
    query=question, top_k=5,
    seed_entities=["Nimbus Analytics"],           # merged with the query's own seeds
    exclude_docs=[s.doc.id for s in r1.sources],  # don't re-retrieve consumed docs
)

种子提及会通过别名索引解析,因此可以使用自由文本实体名称。查询路径保持确定性,不依赖 LLM——规划智能由调用方提供。

MCP 服务:将 hubmesh 接入任意 Agent
pip install "hubmesh[mcp]"
python -m spacy download en_core_web_sm
{"mcpServers": {"hubmesh": {"command": "hubmesh-mcp"}}}

通过 stdio 将规划器作为确定性操作工具暴露出来—— index_corpus、retrieve(可通过种子引导,如上所述)、resolve_entities、 entity_neighbors、path_between、get_document、graph_stats、 list_corpora。你的 Agent 负责求解:它会拆解问题、 读取每一步,并确定下一步的方向;服务则在几毫秒内作答, 且不会调用任何大模型。语料库以纯 JSON/NPZ 格式 持久化在 ~/.hubmesh/corpora 下。

服务会在启动时于后台预热模型并加载持久化语料库 (首次运行约需 5-10 秒),因此工具调用从一开始就能保持快速—— 这对有严格超时限制的连接器客户端(Perplexity 等)很重要。

对于基于 Web 的连接器客户端,可原生提供 SSE 服务——无需网关 进程:

export HUBMESH_API_KEY="$(openssl rand -hex 24)"   # any strong secret
hubmesh-mcp --transport sse --port 8000 --allow-tunnel
ngrok http 8000     # paste https://<your-url>/sse into the connector

通过隧道提供服务必须使用 API key(没有 API key,服务会拒绝启动), 且默认采用只读模式——传入 --allow-writes 可保持 index_corpus 启用。客户端必须发送 Authorization: Bearer <key>。如果你的连接器客户端无法设置 请求头,隧道边缘必须在添加上游请求头之前自行对调用方进行身份验证 (ngrok OAuth / IP 限制流量策略、Cloudflare Access,……)。对于匿名 流量注入请求头,会让所有调用方都获得完整的读取权限(只读模式能防止语料库 被替换,但无法防止信息泄露;get_document 会返回完整 文本)。既无法发送请求头、又无法通过具备身份验证功能的边缘进行连接的客户端,不支持访问私有语料库。

隧道使用说明(来自一次正在运行的 Perplexity 集成):ngrok 可用 (包括免费套餐);cloudflared 快速隧道会缓冲 SSE 正文 并导致工具调用挂起;这里不需要 supergateway,且它会在重新连接时崩溃。 --allow-tunnel 会接受隧道转发的 Host 请求头——如果不使用该选项, 代理请求会得到 421 Misdirected Request。

完整的实测报告——包括设置说明、错误解码器、通过 Perplexity 运行的 9/9 测试套件,以及关于推理模型行为的两项发现——详见 docs/perplexity.md。

长文档分块处理
from hubmesh import chunk_by_sentences, chunk_documents

chunks = chunk_documents(
    [{"id": "doc1", "text": long_text}, ...],
    strategy="sentences", target_tokens=200,
)
# Then embed chunks and index normally

安装

pip install hubmesh                   # core
pip install "hubmesh[qdrant]"         # Qdrant adapter
pip install "hubmesh[chroma]"         # Chroma adapter
pip install "hubmesh[kg]"             # entity-linked KG (spaCy)
pip install "hubmesh[linker]"         # embedding-based entity linker
pip install "hubmesh[all]"            # everything
python -m spacy download en_core_web_sm   # required for KG mode

设计

KG 模式——经过基准测试的生产路径:

query ─► spaCy NER ─► alias index ─► entity seeds ─► Personalized PageRank over the corpus KG
  │                   (fallback: entities of the top-3 cosine documents)              │
  └───────────► cosine similarity against every document ─────────────────────────────┤
                                                                                      ▼
            3·minmax(cosine) + 1·minmax(pooled PPR) + 1·minmax(per-anchor geomean)   [weighted sum]
                                                                                      ▼
                          budget-aware packing ─► context + sources + reasoning paths

kNN 模式(无 KG;用于原型设计):第一阶段使用 ANN → 构建有上限的诱导邻近 子图 → 从 ANN 种子执行 PPR → 使用相同的评分和打包流程。 社区锚定功能适用于单主题检索,默认关闭。

每一层都可独立测试和替换。适配器会封装你现有的 向量数据库,因此无需迁移——请注意,KG 模式会对每个文档评分(每个存储版本只收集一次向量 并缓存),且仅在种子回退时使用存储的 ANN 索引。

基准测试

在合并的干扰段落语料上评估支持事实段落召回率。每一行都是一项独立实验:文档表示方式和嵌入模型会显著改变绝对数值,因此不同表示方式的结果不可横向比较。协议、消融实验和限制见 BENCHMARKS.md。

完整 HotpotQA dev(7,405 个问题,66,581 个合并段落),hubmesh 对比朴素余弦,v0.4 默认设置:

表示方式 · 嵌入模型朴素 @10hubmesh @10Δ @10Δ @5Δ @2
仅正文 · MiniLM-L669.3%75.2%+5.90+4.21−0.75
标题+正文 · MiniLM-L670.0%77.3%+7.24+5.88+0.25
标题+正文 · bge-m383.5%84.8%+1.38−1.41−9.09

需要双向解读。使用较小的嵌入模型时,图层可将深层召回率提高 5–7 个百分点;使用强模型时,深层召回率的提升缩小到 +1.4,而默认设置会损害排名靠前的结果(recall@2 时 −9.1)。收敛项以牺牲排名靠前结果的精度来换取深层召回率:对于使用强嵌入模型、关注 top-2/top-5 的工作负载,请使用 use_convergence=False 或纯余弦,并先在自己的工作负载上评估,再决定是否全面启用图层。

**完整 MuSiQue-Ans dev(2,417 个问题,MiniLM,仅正文),hubmesh 对比朴素方法,recall@10 及配对 95% CI:**总体 +3.67 [+3.00, +4.39](@2 时 +2.2,@5 时 +3.3);按跳数分别为 +2.9 / +4.1 / +5.3(n = 1,252 / 760 / 405)。增益随跳数增加;在 MuSiQue 上,hubmesh 在 recall@2 上也优于朴素方法。

评分带来的提升(HotpotQA N=500,仅正文,recall@10):在同一图、种子、回退机制和打包器上,余弦融合评分达到 0.871,纯结构信号(仅 PPR)为 0.676——+19.5 个百分点 [+16.3, +22.7](MuSiQue N=300:+16.3)。早期版本曾引用与 HippoRAG 风格排序器对比的 +29.8;该对比也改变了处理流程,因此不再将其归因于评分。

**收敛项(默认开启):**在完整 MuSiQue dev 上,相比关闭收敛,@10 提升 +0.9 个百分点;在 HotpotQA N=500 上提升 +1.1。相同位置使用单次求解的对数池化信号,整体表现与之相当;在三跳和四跳时,几何均值仍保留约 1 个百分点的提升。多种子查询的成本约为 1.5–2×(仍不消耗 LLM token,且结果确定)。

延迟:在 7K 节点的 KG 上,每个查询平均约 22 ms,p95 为 26 ms(PPR 矩阵缓存后)。在完整开发集的 66K 段落规模下,曾测得开启收敛时约 3 秒/查询;该测量是在移除每个查询的向量重新收集之前进行的。此后尚未重新测量该规模。

复现(每次运行都会写入一个 JSON,包含逐查询记录和清单;清单记录 commit、dirty 标志以及源代码/测试框架内容哈希):

python benchmarks/run_hotpotqa.py --n 500 --kg --out hotpot.json
python benchmarks/run_musique.py  --n 300 --kg --out musique.json
python benchmarks/run_ablation_coherence.py --dataset musique --n 2417
python benchmarks/profile_query.py        # latency profile

状态

预 alpha(v0.4.2)。核心算法已实现并验证;提供内存、Qdrant 和 Chroma 适配器;实体关联 KG 支持 spaCy NER 和基于 LLM 的抽取(两者都能感知链接器);基于别名索引的实体消歧;NNSI-KG 评分(默认开启多源收敛,可选启用 hub 折扣 PPR);由 Agent 驱动的迭代式多跳检索,通过 seed_entities / exclude_docs 实现;MCP 操作员服务(hubmesh-mcp,原生 SSE),支持 JSON/NPZ 语料持久化;文档分块;推理路径解释;PPR 缓存延迟优化。Pinecone / pgvector / Weaviate 适配器和更多多跳基准测试列为适合新手的首批议题。

致谢

多组件评分模式改编自以下文献介绍的 Network Node Significance Index (NNSI) 框架:

D. S. K. Naidu 等,“基于软件定义网络中的图论改进网络拓扑的框架”,载于 Internet Computing, Internet of Things, Artificial Intelligence, and Applications,Communications in Computer and Information Science,第 2934 卷,H. R. Arabnia、L. Deligiannidis、 K. Ferens、F. Ghareh Mohammadi、F. Shenavarmasouleh 和 S. Amirian 编。 Cham:Springer,2026 年,第 3–18 页。 doi:10.1007/978-3-032-22190-2_1

@inproceedings{naidu2026nnsi,
  author    = {Naidu, Datta Sai Krishna and others},
  title     = {A Framework for Improving Network Topology Based on Graph Theory
               in Software-Defined Networking},
  booktitle = {Internet Computing, Internet of Things, Artificial Intelligence,
               and Applications},
  series    = {Communications in Computer and Information Science},
  volume    = {2934},
  editor    = {Arabnia, Hamid R. and Deligiannidis, Leonidas and Ferens, Ken and
               Ghareh Mohammadi, Farid and Shenavarmasouleh, Farzan and
               Amirian, Soheyla},
  pages     = {3--18},
  publisher = {Springer},
  address   = {Cham},
  year      = {2026},
  doi       = {10.1007/978-3-032-22190-2_1},
  isbn      = {978-3-032-22189-6}
}

本文将 NNSI 从 SDN 拓扑优化改用于检索规划;将其应用于基于实体链接的 KG 检索是本研究的新内容。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。