This notebook presents an interactive visualization of the legal knowledge graph.
The graph makes explicit the structural relationships between statutory provisions that are otherwise difficult to observe through text-only retrieval.

This visualization serves both as a diagnostic tool and as an explanatory aid for understanding how graph enhancement influences retrieval and downstream answer generation.

1 Build and Load the Graph

After pull the project source code, the preprocessing stage constructs a legal knowledge graph to capture structural relationships:

git clone https://github.com/Fan-Luo/Legal-RAG.git
pip install -e .
python -m scripts.preprocess_law
python -m scripts.build_graph

2 What This Graph Represents

Nodes correspond to individual legal provisions (e.g., articles or clauses).

Edges encode structural relationships, capturing referential and contextual dependencies among laws.

The graph is constructed offline from preprocessed legal texts and stored as a static HTML artifact for reproducible inspection.

from legalrag.config import AppConfig
from legalrag.retrieval.graph_store import LawGraphStore

cfg = AppConfig.load(None)
store = LawGraphStore(cfg)
[Graph] Loaded 1260 law nodes
[Graph] Built adjacency: 2640 edges
Example graph node:
  Article ID   : 142
  Article No   : 第一百四十二条
  Law          : 中华人民共和国民法典
  Chapter      : 六章 民事法律行为
  Section      : 三节 民事法律行为的效力

  Neighbors:
    -  141 | rel=prev   | conf=1.00 | evidence=None
    -  143 | rel=next   | conf=1.00 | evidence=None
    -  466 | rel=cited  | conf=0.90 | evidence={'span': [30, 37], 'text': '第一百四十二条'}

3 Graph Walk Retrieval

Graph-based expansion performs a bounded breadth-first search (BFS) over the legal knowledge graph, starting from one or more seed articles. The goal is to retrieve a localized subgraph centered on the query nodes, while allowing fine-grained control over relation types, confidence thresholds, and the total number of returned nodes. The resulting nodes are used to induce a subgraph for visualization or downstream analysis.

start_ids = ["582"]
law_nodes = store.walk(start_ids, limit = 30)
node_ids = [node.article_id for node in law_nodes] + start_ids