Which TextSplitter to Use for GraphRAG in Semantica?

Use the graph_based TextSplitter method for GraphRAG in Semantica, as it preserves graph topology and injects node/edge metadata into each chunk.

For Graph Retrieval-Augmented Generation (GraphRAG) workloads, chunking strategy directly impacts retrieval quality. The Semantica library provides purpose-built splitting methods that align chunk boundaries with knowledge graph structures. This article explains how to configure and implement the correct TextSplitter for GraphRAG in Semantica based on the actual source code implementation.

How Semantica's TextSplitter Architecture Works

The splitting functionality in Semantica is unified under the TextSplitter class in semantica/split/splitter.py. This class acts as a factory that dispatches to specialized chunker implementations based on the method parameter.

The graph_based method specifically uses GraphBasedChunker to:

  • Respect node and edge groupings during chunking
  • Prevent relationships from being split across chunk boundaries
  • Inject graph metadata into each Chunk object via the metadata dictionary

Other relevant methods include entity_aware (for named-entity continuity) and relation_aware (for complete triple preservation), but graph_based is the explicit choice for full graph-structure alignment.

Why Graph-Based Splitting Matters for GraphRAG

Traditional text splitters like recursive character or token-based approaches ignore semantic relationships. In semantica/split/splitter.py, the GraphBasedChunker implementation solves this by accepting an external graph that guides chunking decisions.

Key benefits for GraphRAG pipelines:

  • Topology preservation: Nodes that are densely connected in the source graph tend to appear together in chunks
  • Metadata propagation: Each chunk receives graph_nodes and graph_edges keys in its metadata field
  • Sub-graph retrieval: Downstream RAG components can use the metadata to locate and traverse the relevant graph neighborhood

Configuring the Graph-Based TextSplitter

Basic Usage with TextSplitter Class

from semantica.split import TextSplitter

raw_text = """
Apple Inc. was founded by Steve Jobs, Steve Wozniak, and Ronald Wayne.
The company pioneered the personal computer, the iPod, the iPhone,
and the iPad. Its ecosystem includes hardware, software, and services.
"""

splitter = TextSplitter(
    method="graph_based",      # Specifies GraphBasedChunker

    chunk_size=500,            # Target size in characters/tokens

    chunk_overlap=100,         # Context overlap between chunks

)

chunks = splitter.split(raw_text)

for i, chunk in enumerate(chunks, 1):
    print(f"Chunk {i}:")
    print(f"  text: {chunk.text[:80]!r}...")
    print(f"  metadata: {chunk.metadata}")   # Contains graph_nodes, graph_edges

Source: README.md line 627 and docs/reference/split.md lines 38-50.

Direct Function: split_graph_based

For cases where you want explicit graph injection, use the convenience function from semantica/split/methods:

from semantica.split.methods import split_graph_based

knowledge_graph = {
    "nodes": ["Apple Inc.", "Steve Jobs", "iPhone"],
    "edges": [
        ("Apple Inc.", "founded_by", "Steve Jobs"),
        ("Apple Inc.", "produces", "iPhone")
    ]
}

chunks = split_graph_based(
    text=raw_text,
    graph=knowledge_graph,      # Graph guides chunking boundaries

    chunk_size=800,
    chunk_overlap=150,
)

for chunk in chunks:
    print(chunk.metadata.get("graph_nodes"))

Source: semantica/split/split_usage.md lines 239-241.

Complete GraphRAG Pipeline Integration

The following example demonstrates end-to-end integration using TextSplitter for GraphRAG in Semantica:

from semantica.split import TextSplitter
from semantica.vector_store import VectorStore
from semantica.rag import GraphRAG

# 1. Split with graph-based chunking

splitter = TextSplitter(
    method="graph_based",
    chunk_size=1024,
    chunk_overlap=200
)
chunks = splitter.split(raw_text)

# 2. Index embeddings and metadata

vs = VectorStore(backend="pgvector")
vs.index(chunks)

# 3. Initialize GraphRAG with graph reference

rag = GraphRAG(vector_store=vs, graph=knowledge_graph)

# 4. Query with graph-aware retrieval

answer = rag.ask("Who founded Apple Inc.?")
print(answer)

Source: semantica/vector_store/vector_store_usage.md lines 953-958.

Comparing Splitter Methods for Graph Workloads

Method Best For Key Behavior
graph_based GraphRAG — full pipeline integration Uses supplied graph to guide chunking; injects complete node/edge metadata
entity_aware KG extraction focusing on named entities Guarantees entity spans never cross chunk boundaries
relation_aware Triple-preserving pipelines Keeps subject-predicate-object groups intact

For GraphRAG specifically, only graph_based provides the metadata hooks required for vector-store indexing and subsequent graph traversal during retrieval.

Key Source Files

Path Purpose
semantica/split/splitter.py Core TextSplitter class and GraphBasedChunker implementation
semantica/split/methods.py Convenience functions including split_graph_based
semantica/split/split_usage.md Usage examples and parameter documentation
docs/reference/split.md Complete method reference and selection guide

Summary

  • Set method="graph_based" in TextSplitter for GraphRAG workloads
  • Supply a knowledge graph to split_graph_based() or via the RAG pipeline to preserve structural relationships
  • Access chunk.metadata["graph_nodes"] and chunk.metadata["graph_edges"] for downstream graph traversal
  • The unified TextSplitter interface allows method swapping without code changes

Frequently Asked Questions

What makes graph_based different from relation_aware splitting?

graph_based accepts an external graph structure that actively guides chunk boundaries, while relation_aware only ensures complete subject-predicate-object triples remain intact without external graph input. For GraphRAG, you need the metadata injection and topology awareness that graph_based provides.

Can I use graph_based without a pre-constructed knowledge graph?

No. The graph_based method requires a graph parameter (dict or graph object) that defines nodes and edges. Without this, the chunker cannot align boundaries to graph structure. Use entity_aware or relation_aware if you lack a graph but still want some semantic preservation.

How does graph metadata appear in the chunk output?

Each Chunk object from graph_based splitting contains a metadata dictionary with at least two keys: graph_nodes (list of node identifiers present in that chunk) and graph_edges (list of edge tuples). These are populated by GraphBasedChunker during the split operation.

Is there a performance cost to graph_based splitting?

Yes. GraphBasedChunker performs graph traversal and boundary optimization that adds overhead compared to simple character-based splitting. However, for GraphRAG accuracy, this cost is justified and typically occurs only during indexing, not at query time.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →