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
| Subagent | Asks | Answers | Evidence it brings |
|---|---|---|---|
KromaAgent (KROMA) | Is this source class the same as this target class? | yes, no | Character n-gram similarity of names, plus agreement of already matched parents |
ExtractionAgent | How does this class relate to this candidate? | subClassOf, part_of, none | Label rules (a head word gives subClassOf, a modifier gives part_of) and the parents of similar classes |
ReasoningAgent | Under which candidate does this unmatched class belong? | a candidate code, or none | The counterparts of its nearest matched ancestors, and their descendants two levels down |
ValidationAgent | (asks nothing) | removes the weaker side of each conflict | One-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
- Evidence. At or above
accept, the question takes the answer the evidence supports; at or belowreject, the fallback. No model is called. - Local model. The rest go to the local model in batches of 8; an answer with confidence at least
local_trustis kept. - 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 markedbudget.
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.