Agentic Ontologist

Agents

The orchestrator and its agents

One orchestrator and four memory-augmented subagents integrate two ontologies. Every question a subagent asks goes to the cheapest tier that can settle it.

Subagents

flowchart LR
    S["Source + target ontology"] --> K["KROMA: matching"]
    K --> V["Validation: remove conflicts"]
    V --> R["Reasoning: place unmatched classes"]
    S --> E["Extraction: missing edges"]
    K -.questions.-> C{{"Orchestrator"}}
    E -.questions.-> C
    R -.questions.-> C
    C --> T1["Evidence"]
    C --> T2["Local model"]
    C --> T3["API model"]
    V --> B[("Blackboard")]
    R --> B
    E --> B
SubagentAsksAnswersEvidence it brings
KromaAgent (KROMA)Is this source class the same as this target class?yes, noCharacter n-gram similarity of names, plus agreement of already matched parents
ExtractionAgentHow does this class relate to this candidate?subClassOf, part_of, noneLabel rules (a head word gives subClassOf, a modifier gives part_of) and the parents of similar classes
ReasoningAgentUnder which candidate does this unmatched class belong?a candidate code, or noneThe counterparts of its nearest matched ancestors, and their descendants two levels down
ValidationAgent(asks nothing)removes the weaker side of each conflictOne-to-many matches and criss-cross matches that would collapse a hierarchy

KROMA settles exact label and synonym matches first, and never asks again about a class it settled, which is KROMA's refinement step in this setting. Tied conflicts go to a review queue for a person.

Routing

  1. Evidence. At or above accept, the question takes the answer the evidence supports; at or below reject, the fallback. No model is called.
  2. Local model. The rest go to the local model in batches of 8; an answer with confidence at least local_trust is kept.
  3. API model. The rest go to the API model in batches of 20, while the Budget (calls or list-price dollars) lasts. Past it, the local answer stands and the decision is marked budget.

A model that fails or leaves a question out of its reply does not stop the run: the question falls back to the next answer available.

Recalibration

Every escalated question the local model also answered is a labeled example of how far the local model can be trusted. Escalations alone only show the local model's unsure answers, so the controller also audits a random 10% of the answers it would keep, asking the API model too. Questions are settled in rounds of 160; after each round, local_trust becomes the lowest confidence at which the local model agreed with the API model at least 90% of the time, over at least 10 examples, or NEVER (above 1) when no confidence qualifies, so every question the evidence does not settle goes up until the comparisons bring the threshold back down. Each change is written to the blackboard's log.

Running it

from agentic_ontologist.workflow import Budget, ClaudeCodeModel, Controller, OllamaModel, Workflow, load_owl

source, target = load_owl("data/MouseHuman/mouse.owl"), load_owl("data/MouseHuman/human.owl")
controller = Controller(local=OllamaModel("llama3.1"), api=ClaudeCodeModel("claude-sonnet-5-5"),
                        budget=Budget(api_calls=20))
result = Workflow(controller).integrate(source, target, place=100)
print(len(result.matches), result.validation.removed, result.tiers)

Cost

Every model call is recorded on agentic_ontologist.costs.METER with its tokens, seconds, and list-price dollars. experiments/agentic_workflow compares the routed policy with a local model alone, an API model alone, a call cap, and evidence alone, on all three tasks; see Experiments and the live showcase.