Best-effort condensing of an ontology graph before it becomes prompt text.
Only the vector-retrieval mode ever bounded how much ontology reached the LLM.
selected_single_ontology (the default) and fixed_single_ontology serialize
the whole selected catalog ontology into every prompt, and the facts fan-out
serializes the union of every ontology artifact -- all with no cap, no sampling
and no truncation. On a large catalog that is the context blow-up; nothing else
in the pipeline notices.
This module trims a graph toward a triple budget by dropping the
least-load-bearing triples first, in the order established by
:data:~ontocast.onto.graph_prune.BFS_PREDICATE_PRIORITY. It is deliberately
best-effort: it will never drop labels, types, hierarchy or domain/range to
hit a number. A budget that cannot be met without cutting into those is reported
as a warning and the graph is passed through oversized, because silently
removing the schema the model needed produces a bad extraction that looks like a
bad model -- the most expensive failure mode this pipeline has.
CondenseReport
Bases: BaseModel
What condensing did, for telemetry and for explaining a warning.
Source code in ontocast/onto/ontology_condense.py
| class CondenseReport(BaseModel):
"""What condensing did, for telemetry and for explaining a warning."""
triples_before: int = Field(description="Triple count on entry")
triples_after: int = Field(description="Triple count after condensing")
max_triples: int | None = Field(
default=None, description="Budget applied; None means no budget"
)
dropped_noise: int = Field(default=0, description="Header/list plumbing removed")
dropped_structural: int = Field(
default=0, description="Generic types, stub restrictions, orphan bnodes"
)
dropped_glosses: int = Field(
default=0, description="Comments, definitions, scope notes, alt labels"
)
over_budget: bool = Field(
default=False,
description="Still above budget after condensing; passed through oversized",
)
@property
def changed(self) -> bool:
"""Whether anything was removed at all."""
return self.triples_after != self.triples_before
def as_metrics(self) -> dict[str, int | bool | None]:
"""Flat mapping for the retrieval-metrics payload."""
return {
"triples_before": self.triples_before,
"triples_after": self.triples_after,
"max_triples": self.max_triples,
"dropped_noise": self.dropped_noise,
"dropped_structural": self.dropped_structural,
"dropped_glosses": self.dropped_glosses,
"over_budget": self.over_budget,
}
|
changed
property
Whether anything was removed at all.
as_metrics()
Flat mapping for the retrieval-metrics payload.
Source code in ontocast/onto/ontology_condense.py
| def as_metrics(self) -> dict[str, int | bool | None]:
"""Flat mapping for the retrieval-metrics payload."""
return {
"triples_before": self.triples_before,
"triples_after": self.triples_after,
"max_triples": self.max_triples,
"dropped_noise": self.dropped_noise,
"dropped_structural": self.dropped_structural,
"dropped_glosses": self.dropped_glosses,
"over_budget": self.over_budget,
}
|
condense_graph_for_prompt(graph, max_triples)
Trim graph toward max_triples, dropping the least useful triples first.
Passes are applied in increasing order of harm, stopping as soon as the graph
fits: header/list noise, then structural scaffolding, then glosses. Structure
that lets the model name and place a term is never dropped.
Parameters:
| Name |
Type |
Description |
Default |
graph
|
RDFGraph
|
Ontology graph destined for a prompt. Not mutated.
|
required
|
max_triples
|
int | None
|
Triple budget, or None to disable condensing entirely.
|
required
|
Returns:
Source code in ontocast/onto/ontology_condense.py
| def condense_graph_for_prompt(
graph: RDFGraph,
max_triples: int | None,
) -> tuple[RDFGraph, CondenseReport]:
"""Trim ``graph`` toward ``max_triples``, dropping the least useful triples first.
Passes are applied in increasing order of harm, stopping as soon as the graph
fits: header/list noise, then structural scaffolding, then glosses. Structure
that lets the model name and place a term is never dropped.
Args:
graph: Ontology graph destined for a prompt. Not mutated.
max_triples: Triple budget, or ``None`` to disable condensing entirely.
Returns:
The condensed graph (or ``graph`` itself when nothing was done) and a
:class:`CondenseReport` describing what happened.
"""
before = len(graph)
report = CondenseReport(
triples_before=before, triples_after=before, max_triples=max_triples
)
if max_triples is None or before <= max_triples:
return graph, report
working = graph.copy()
report.dropped_noise = _drop_predicates(working, NOISY_EXPANSION_PREDICATES)
if len(working) > max_triples:
structural_before = len(working)
strip_redundant_generic_types(working)
prune_degenerate_restriction_bnodes(working)
prune_orphaned_bnode_subjects(working)
report.dropped_structural = structural_before - len(working)
if len(working) > max_triples:
report.dropped_glosses = _drop_predicates(working, GLOSS_PREDICATES)
report.triples_after = len(working)
report.over_budget = len(working) > max_triples
if report.over_budget:
logger.warning(
"Ontology context still exceeds the prompt budget after condensing "
"(%d > %d triples; was %d). Passing it through rather than dropping "
"labels, types, hierarchy or domain/range, which the model needs to "
"use the schema at all. Reduce the catalog, split it, or switch to "
"ONTOLOGY_CONTEXT_MODE=selected_vector_search_ontology, which "
"retrieves only the relevant part.",
report.triples_after,
max_triples,
before,
)
else:
logger.info(
"Condensed ontology context %d -> %d triples for a %d budget "
"(noise=%d, structural=%d, glosses=%d).",
before,
report.triples_after,
max_triples,
report.dropped_noise,
report.dropped_structural,
report.dropped_glosses,
)
return working, report
|