Skip to content

API Reference

Note: This is a manually-maintained API reference. For the authoritative API, read the source on GitHub.

runic.rag is a thin Graph-RAG SDK layered on runic.ogm: it adds entity/relation extraction, embeddings, graph storage, and hybrid (vector + fulltext + graph-expansion) retrieval. The public surface is the GraphRAG facade plus the domain value objects, configuration, ontology, OGM models, default adapters, and ports needed to extend or test the pipeline. Everything imports from runic.rag. For the end-to-end workflow, start with the quickstart; this page is the reference.

python
from runic.rag import GraphRAG, Ontology, RagSettings

GraphRAG facade

runic.rag.facade.GraphRAG

The single entry point. It hides all wiring: given a driver (or a prebuilt store) plus its ports, it composes an ingestion service and a retrieval service and exposes four verbs — bootstrap_schema(), ingest_text(), ingest_document(), and query(). Construct it with with_defaults() for the batteries-included path, or call the constructor directly to swap any stage.

with_defaults

python
@classmethod
def with_defaults(
    cls,
    driver: Any = None,
    *,
    settings: RagSettings | None = None,
    ontology: Ontology | None = None,
    document_parser: DocumentParser | None = None,
    document_chunker: DocumentChunker | None = None,
) -> GraphRAG: ...

Build a fully-wired GraphRAG with the production adapters. All arguments are optional — the driverless form is the documented default:

  • driverNone builds a driver from settings.backend (FalkorDB on localhost by default, otherwise Neo4j/Memgraph/ArcadeDB/AGE).
  • settingsNone calls load_settings() (reads the environment + .env).
  • ontologyNone uses Ontology.default().
  • document_parser, document_chunkerNone (the default) keeps the built-in ingest_document path. Pass already-built file-oriented ports (e.g. from the runic-rag-docling add-on) to parse/chunk documents structure-aware. This path imports no document backend.
python
from runic.rag import GraphRAG, RagSettings

rag = GraphRAG.with_defaults(settings=RagSettings())

INFO

To select and configure a backend explicitly (e.g. build a driver with create_driver(...)), see configuration.

Constructor (extension seam)

python
def __init__(
    self,
    driver_or_store: Any,
    *,
    ontology: Ontology,
    chunker: Chunker,
    extractor: Extractor,
    embedder: Embedder,
    resolver: EntityResolver,
    retrievers: dict[str, Retriever],
    reranker: Reranker,
    synthesizer: Synthesizer,
    settings: RagSettings,
    budget: BudgetGuard | None = None,
    document_parser: DocumentParser | None = None,
    document_chunker: DocumentChunker | None = None,
) -> None: ...

Every collaborator is an injected port, so the whole pipeline is swappable and unit-testable with fakes. driver_or_store may be an OGM driver (wrapped in a GraphStore) or an already-built store. retrievers maps a retriever name to a Retriever; the planner expects the keys "vector", "fulltext", "local", and "highlevel". document_parser and document_chunker are the optional file-oriented ingestion ports (both default None); they are forwarded to the ingestion service and only consulted by ingest_document — see Ports.

Verbs

MethodSignatureDescription
bootstrap_schemabootstrap_schema() -> NoneCreate the entity types and indexes for the ontology. Idempotent.
ingest_textingest_text(text: str, *, source: str) -> IngestionReportIngest text tagged with the required source; return the report.
ingest_documentingest_document(path: str | Path) -> IngestionReportLoad and ingest a .txt/.md/.pdf file (auto-detected); return the report.
queryquery(q: str, *, mode: str = "auto") -> AnswerAnswer q using the configured retrievers; return a cited Answer.

mode is one of "auto", "local", or "hybrid"; any other value raises ValueError. auto is a cheap heuristic (not an LLM classifier): it picks local when the query has 8 or fewer tokens and contains no broad-cue word (all, across, compare, overall, themes, trends, summarize, summary, relationship, relationships, everything), and hybrid otherwise. See retrieval for what each mode does.

WARNING

bootstrap_schema() raises ValueError when embedding_dim <= 0 — the vector index needs a real dimension. Keep RUNIC_RAG_EMBEDDING_DIM aligned with your embedding model (1536 for text-embedding-3-small).


Ontology

runic.rag.ontology.Ontology

Bundles the entity-type vocabulary with its backing OGM Entity subclasses. The ontology drives both schema bootstrap and which types the extractor is allowed to emit.

python
def __init__(self, entity_models: list[type[Entity]] | None = None) -> None: ...

Construct directly with explicit Entity subclasses, or use the two factories.

MemberSignatureDescription
defaultOntology.default() -> OntologyThe generic built-in subtypes: Person, Organization, Location, Concept, Product, Event.
from_typesOntology.from_types(type_names: list[str]) -> OntologyBuild a tuned vocabulary; reuses built-in subtypes by name, else generates one dynamically.
entity_typesentity_types() -> list[str]Ordered list of entity-type names in this ontology.
subtype_forsubtype_for(type: str) -> type[Entity]The Entity subclass for type; falls back to the base Entity for unknown names.
schema_modelsschema_models() -> list[type]All OGM models needed to bootstrap: base Entity, every subtype, Chunk, and RelationEdge (deduped, base-first).
python
from runic.rag import Ontology

generic = Ontology.default()
tuned = Ontology.from_types(["Company", "Executive", "Industry", "FinancialMetric", "Market"])

See ontologies for tuning guidance and custom subclasses.


RagSettings & load_settings

runic.rag.config.RagSettings, runic.rag.config.load_settings

Strongly-typed runtime configuration via pydantic-settings. Field names mirror the RUNIC_RAG_* environment variables; OPENAI_API_KEY and OLLAMA_BASE_URL are read unprefixed.

python
class RagSettings(BaseSettings): ...

def load_settings() -> RagSettings: ...

load_settings() calls dotenv.load_dotenv() first (so a local .env is visible to pydantic-settings and to the OpenAI client), then returns a validated RagSettings. Key defaults: llm_model="gpt-5.4-nano", embedding_model="text-embedding-3-small", embedding_dim=1536, backend="falkordb", top_k=10, max_hops=2. The full environment table lives in configuration.


Domain value objects

runic.rag.domain

All domain value objects are frozen pydantic v2 models — immutable and deliberately decoupled from the OGM node models (e.g. the domain Chunk is distinct from the OGM Chunk node).

Ingestion side

Chunk

A contiguous slice of source text produced by a chunker.

FieldTypeDescription
idstrStable chunk identifier.
textstrThe chunk text.
seqintOrdinal position within the source.
sourcestrOrigin tag (file path or caller-supplied source).

ExtractedEntity

An entity surfaced by the extractor from a chunk.

FieldTypeDescription
namestrSurface name as extracted.
typestrEntity-type name (from the ontology vocabulary).
descriptionstrOptional one-line description (default "").

ExtractedRelation

A directed relation between two extracted entities (by name).

FieldTypeDescription
sourcestrSource entity name.
targetstrTarget entity name.
rel_typestrRelation type label.
descriptionstrOptional description (default "").
confidencefloatExtractor confidence in [0, 1] (default 1.0).

Extraction

The full set of entities and relations extracted from one chunk.

FieldTypeDescription
entitieslist[ExtractedEntity]Extracted entities (default empty).
relationslist[ExtractedRelation]Extracted relations (default empty).

IngestionReport

runic.rag.services.ingestion.IngestionReport

Returned by ingest_text() and ingest_document() — frozen counts of what was written this run. You receive it from the return value; it is not imported from runic.rag directly.

FieldTypeDescription
chunksintChunks persisted.
entitiesintDistinct entities upserted.
relationsintRelation edges created.
mentionsintChunk→entity mention links created.

Retrieval side

ScoredKey

FieldTypeDescription
keystrCanonical entity/chunk key.
scorefloatNormalized similarity score in [0, 1].

EntityHit

An entity returned by retrieval, with its relevance score.

FieldTypeDescription
canonical_keystrCanonical entity key.
namestrEntity name.
typestrEntity-type name.
descriptionstrEntity description.
scorefloatRelevance score.

ChunkHit

A source chunk returned by retrieval, with its relevance score.

FieldTypeDescription
idstrChunk id.
textstrChunk text.
sourcestrOrigin tag.
scorefloatRelevance score.

RelationHit

A relation edge discovered while expanding the entity neighbourhood.

FieldTypeDescription
source_keystrSource entity key.
target_keystrTarget entity key.
rel_typestrRelation type label.
descriptionstrRelation description.

RetrievalContext

The assembled evidence for a query.

FieldTypeDescription
querystrThe originating query string.
entitieslist[EntityHit]Retrieved entities (default empty).
chunkslist[ChunkHit]Retrieved source chunks (default empty).
relationslist[RelationHit]Expanded relations (default empty).

Answer side

Citation

A reference to a source chunk supporting an answer.

FieldTypeDescription
chunk_idstrId of the cited chunk.
sourcestrOrigin tag of the cited chunk.
textstrThe cited chunk text.

Answer

The result of query(): a synthesized answer with its supporting evidence.

FieldTypeDescription
textstrThe synthesized answer text.
citationslist[Citation]Supporting citations (default empty).
contextRetrievalContext | NoneThe evidence used, or None.

INFO

Answer.context may be None — always guard for it before reading context.chunks or context.entities.


OGM models

runic.rag.models

These map directly onto graph nodes and edges via runic.ogm. Embedding fields are typed Vector | None, which drives vecf32() on FalkorDB so the KNN index works.

Entity

Entity(Node, labels=["Entity"], primary_label="Entity") — a canonical knowledge-graph entity.

FieldDeclarationDescription
canonical_keyField(primary_key=True)Primary key.
nameField(index_type="FULLTEXT")Fulltext-indexed surface name.
typeField(index=True)Indexed entity-type name (in addition to the subtype label).
descriptionField(default="", index_type="FULLTEXT")Fulltext-indexed description.
embeddingField(default=None, index_type="VECTOR")Vector | None; backs the vector index.
relatedRelation("RELATES_TO", direction="OUTGOING", target="Entity", edge_model=RelationEdge)Outgoing relations to other entities.

SubtypesPerson, Organization, Location, Concept, Product, Event. Each is an Entity subclass labelled ["Entity", "<Subtype>"] with primary_label="Entity".

ChunkNode

The OGM Chunk node, re-exported as ChunkNode to disambiguate it from the frozen domain Chunk. A persisted source-text chunk and the entities it mentions.

FieldDeclarationDescription
idField(primary_key=True)Primary key.
textField(index_type="FULLTEXT")Fulltext-indexed chunk text.
sourceField(index=True)Indexed origin tag.
seqField(default=0)Ordinal position.
embeddingField(default=None, index_type="VECTOR")Vector | None; backs the vector index.
mentionsRelation("MENTIONS", direction="OUTGOING", target="Entity")Entities this chunk mentions.
python
from runic.rag import ChunkNode  # OGM node
from runic.rag import Chunk      # frozen domain value object

RelationEdge

RelationEdge(Edge, type="RELATES_TO") — the property model for a typed relation between two entities.

FieldDeclarationDescription
rel_typeField(index=True)Indexed relation type label.
descriptionField(default="")Relation description.
confidenceField(default=1.0)Extractor confidence.
source_chunkField(default="")Id of the chunk the relation came from.

Ports

runic.rag.ports

Every collaborator the services depend on is a typing.Protocol (all @runtime_checkable), enabling constructor injection and trivial fakes in tests. Pass your own implementation through the GraphRAG constructor to swap a stage — see Writing custom ports for the how-to and the contract each port must honour.

PortMethodDescription
Chunkersplit(text: str, *, source: str) -> list[Chunk]Split raw text into ordered domain chunks.
DocumentParsersupports(source: str) -> bool; parse(path: str | Path) -> strOptional, file-oriented: turn a document file into normalized text fed to the Chunker.
DocumentChunkersupports(source: str) -> bool; chunk_document(path: str | Path, *, source: str | None = None) -> list[Chunk]Optional, file-oriented: read a document file once and emit ordered chunks directly.
Extractorextract(chunk: Chunk, *, entity_types: list[str]) -> ExtractionExtract entities and relations from one chunk.
Embedderdimension -> int (property); embed(text: str) -> list[float]; embed_batch(texts: list[str]) -> list[list[float]]Turn text into dense vectors; batch order matches input.
EntityResolvercanonical_key(entity: ExtractedEntity) -> str; find_duplicate(entity, embedding, store) -> str | NoneDecide canonical identity and detect existing duplicates.
Retrieverretrieve(query: str, *, top_k: int) -> RetrievalContextBuild a retrieval context for a query.
Rerankerrerank(query: str, contexts: list[RetrievalContext], *, top_k: int) -> RetrievalContextFuse, reorder, and trim contexts into one.
Synthesizersynthesize(query: str, context: RetrievalContext) -> AnswerProduce a cited answer from context.
Writeradd_chunk(chunk_node); upsert_entity(key, name, type, description, embedding); relate(src_key, rel_type, dst_key, description, confidence, source_chunk); mention(chunk_id, entity_key)One graph unit-of-work; changes commit when the context manager exits.
GraphStorebootstrap_schema(); writer() -> AbstractContextManager[Writer]; vector_search(...); fulltext_search(...); get_entities(keys); expand(keys, *, max_hops); chunks_for_entities(keys, *, limit)The backend-isolating graph port; hides dialect differences.

DocumentParser and DocumentChunker are optional, file-oriented ports consulted by ingest_document in the order document_chunker, then document_parser, then the built-in loader — the first one whose supports() returns True wins, and ingest_text() never touches them. Both default to None; the core imports no document backend.

The concrete GraphStore adapter is also exported as GraphStoreAdapter (= runic.rag.store.GraphStore) for advanced wiring.


Default adapters

runic.rag.adapters

with_defaults() wires this production stack. Pass alternatives through the constructor to override any of them.

PortDefault adapter
ChunkerParagraphChunker
ExtractorPydanticAIExtractor
EmbedderOpenAIEmbedder
EntityResolverTwoStageResolver
Retriever ("vector")VectorRetriever
Retriever ("fulltext")FulltextRetriever
Retriever ("local")LocalRetriever
Retriever ("highlevel")HighLevelRetriever
RerankerRRFReranker
SynthesizerPydanticAISynthesizer
GraphStorestore.GraphStore (exported as GraphStoreAdapter)

INFO

CrossEncoderReranker and OllamaEmbedder are exported, opt-in alternatives — they are not wired by with_defaults(). Pass them to the constructor (or set RUNIC_RAG_EMBEDDING_PROVIDER=ollama for the embedder) to use them.

The DocumentParser and DocumentChunker ports have no built-in core adapter — they are provided by the optional runic-rag-docling add-on and injected via the document_parser / document_chunker parameters.


Exceptions

runic.rag.exceptions

ExceptionBaseRaised when
RagErrorExceptionBase class for all runic.rag errors.
BudgetExceededErrorRagErrorA cost budget (LLM calls or tokens) is exceeded.
ConfigErrorRagErrorConfiguration is missing or invalid.

Next steps

See also

runic - Graph schema migrations and OGM for Cypher-based graph databases. · Impressum