{"slug": "local-first-multi-hop-rag-chroma-an-entity-graph-zero-tokens-per-query", "title": "Local-first multi-hop RAG: Chroma + an entity graph, zero tokens per query", "summary": "Hubmesh, a new open-source project, introduces a local-first multi-hop retrieval system that combines Chroma vector search with an entity graph and Personalized PageRank, achieving 75.2% supporting-fact recall@10 on HotpotQA dev without using LLM tokens per query. The system, built by developer DemigodDSK, runs offline in about 100ms on a 30K-doc corpus and is bit-identical across runs, offering a deterministic alternative to LLM-in-the-loop retrieval.", "body_md": "Chroma's sweet spot is local-first: embed your documents, query them\n\non your own machine, no infrastructure ceremony. But local-first RAG\n\nhits a wall on multi-hop questions:\n\n\"Which university did the founder of the company that acquired Polar\n\nMetrics study at?\"\n\nThe answering passage shares almost no vocabulary with the question.\n\nIt's connected to it — through an acquisition, a founder, a biography\n\n— and similarity search can't follow connections. The usual fix is to\n\nput an LLM in the retrieval loop to decompose the question, which\n\nbreaks exactly what makes local-first attractive: now every query\n\ncosts tokens, takes seconds, and returns something different each run.\n\n[hubmesh](https://github.com/DemigodDSK/hubmesh) takes the other road:\n\nkeep retrieval as pure math. At index time it builds an entity–document\n\ngraph from your corpus with spaCy NER (no LLM, no tokens). At query\n\ntime it runs Personalized PageRank from the question's entities over\n\nthat graph and fuses the result with Chroma's cosine scores. The whole\n\nquery path is numpy and scipy: ~100ms on a 30K-doc corpus, offline,\n\nand bit-identical across runs — three properties an LLM-in-the-loop\n\nretriever cannot offer at any price.\n\n```\npip install \"hubmesh[chroma,kg]\"\npython -m spacy download en_core_web_sm\npython\nfrom hubmesh import Planner\nfrom hubmesh.adapters import ChromaStore\nfrom hubmesh.kg import build_entity_kg\nimport spacy\n\nembed = ...  # your embedding callable\n\nstore = ChromaStore.from_documents(docs)                       # ephemeral\n# store = ChromaStore.from_documents(docs, persist_directory=\"./chroma\")\n# store = ChromaStore.from_documents(docs, host=\"localhost\", port=8000)\n\nnlp = spacy.load(\"en_core_web_sm\")\nkg = build_entity_kg(store.get_many(store.all_ids()), nlp=nlp)\nplanner = Planner(store=store, kg=kg, nlp=nlp, embed=embed)\nresult = planner.retrieve(\"Which university did the founder of the \"\n                          \"company that acquired Polar Metrics study at?\",\n                          top_k=10)\nprint([s.doc.id for s in result.sources][:3])\nfor path in result.reasoning:      # the graph route, not a rationalization\n    print(\" -> \".join(path.node_ids))\n```\n\nThe scoring composite has three parts — cosine relevance, PPR\n\ndiffusion, and a *convergence* term that scores each document by the\n\ngeometric mean of diffusion from every question entity separately. A\n\nmulti-hop answer sits at the intersection of the question's anchors;\n\npooled similarity computes a union. Intersections are where bridge\n\ndocuments live. (The formula lineage is a network-topology paper,\n\nNNSI, ICOMP'25 — same idea, different graph.)\n\nFull HotpotQA dev (7,405 questions): 75.2% supporting-fact recall@10\n\nvs 69.3% naive cosine over identical embeddings. MuSiQue 2/3/4-hop:\n\n+6.0/+3.2/+5.0 points. Honest trade: recall@2 dips 0.75 pts under the\n\nconvergence term (flag documented to disable for top-2 workloads).\n\nHarness and raw JSONs ship in the repo.\n\n`pip install \"hubmesh[mcp]\"`\n\nadds an MCP server (in the official MCP\n\nRegistry as `io.github.DemigodDSK/hubmesh`\n\n) with agent-steerable\n\nretrieval: pass `seed_entities`\n\nto aim the next hop at what you just\n\nread, `exclude_docs`\n\nto explore new ground. Local Chroma + local graph\n\n*Repo: github.com/DemigodDSK/hubmesh · MIT · numbers reproducible via benchmarks/*", "url": "https://wpnews.pro/news/local-first-multi-hop-rag-chroma-an-entity-graph-zero-tokens-per-query", "canonical_source": "https://dev.to/demigoddsk/local-first-multi-hop-rag-chroma-an-entity-graph-zero-tokens-per-query-1l43", "published_at": "2026-08-05 01:46:35+00:00", "updated_at": "2026-08-05 02:11:19.737873+00:00", "lang": "en", "topics": ["machine-learning", "artificial-intelligence", "developer-tools", "ai-infrastructure"], "entities": ["Chroma", "Hubmesh", "DemigodDSK", "spaCy", "HotpotQA", "MuSiQue", "MCP", "NNSI"], "alternates": {"html": "https://wpnews.pro/news/local-first-multi-hop-rag-chroma-an-entity-graph-zero-tokens-per-query", "markdown": "https://wpnews.pro/news/local-first-multi-hop-rag-chroma-an-entity-graph-zero-tokens-per-query.md", "text": "https://wpnews.pro/news/local-first-multi-hop-rag-chroma-an-entity-graph-zero-tokens-per-query.txt", "jsonld": "https://wpnews.pro/news/local-first-multi-hop-rag-chroma-an-entity-graph-zero-tokens-per-query.jsonld"}}