mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-15 14:16:05 +00:00
feat(graphrag): seed the walk from what entities are, and rank with passages and vector hits
Graph retrieval tied plain vector search at best and never beat it. Measured
across five corpora, the bottleneck was seeding, not the graph: the walk
started from nodes whose embeddings were computed from bare entity names, and
a whole question shares almost nothing with a name like "Quill".
Extraction now embeds each node from "name (type): description" and each
relationship as the fact it asserts ("Alder streams_to Quill: ..."), stored on
a new nullable graph_edges.fact_embedding column that ensure_vector_schema adds
in place. Entity names are canonicalised (case, punctuation, word breaks and a
cautious plural) so "VECTOR_STORE" and "vector stores" land on one node. Extraction calls run
concurrently (GRAPHRAG_EXTRACTION_WORKERS, default 8) while embedding and graph
writes stay serial on the task thread, so ordering and idempotency are
unchanged; that measured 8.4x faster with identical output.
Retrieval gains per-source options, stored under retrieval.graph and read live
at query time:
- seed_strategy: start from matching entities (default) or matching
relationships, which can reach an entity the question never names;
- passage_nodes (on): walk the source's passages alongside entities, with
PageRank damping 0.5 instead of 0.85;
- blend_vector (on): fuse the graph ranking with the source's vector ranking
by reciprocal rank.
The defaults are the measured-best configuration. Through GraphRAGRetriever,
the new seeding moved recall@4 from 0.41 to 0.68 on a multi-hop corpus and
from 0.50 to 1.00 on the docs corpus, and regressed none of the corpora
measured. Existing graphs keep name-only embeddings until rebuilt.
This commit is contained in:
1 parent
b7e7872bf7
commit
a83e1dc0af
13 files changed
+1577
-79
No files matched your search
@@ -45,6 +45,29 @@ def _patch_embed(monkeypatch):
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _entity_only_ranking(monkeypatch):
|
||||
"""Pin the ranking path these tests were written for.
|
||||
|
||||
Everything here exercises entity-only PPR ranking without vector blending,
|
||||
driven through ``MagicMock`` stores. The shipped default now walks the
|
||||
passages and blends with vector search — covered end to end in
|
||||
``tests/graphrag/test_retriever_default_path.py`` with a store that returns
|
||||
real values. Pinning keeps each test here asserting what it was written to
|
||||
assert, rather than whatever a mock happens to return on a path it never set
|
||||
up.
|
||||
"""
|
||||
from docsgpt.storage.db.source_config import GraphRetrievalConfig
|
||||
|
||||
monkeypatch.setattr(
|
||||
GraphRAGRetriever,
|
||||
"_graph_options",
|
||||
lambda self, source_id: GraphRetrievalConfig(
|
||||
passage_nodes=False, blend_vector=False
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
# ── Fallback to ClassicRAG ────────────────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user