Suggest ontology changes from text (experimental)
Your text already describes your domain. Interview transcripts name the tools people use, the documents they pass on, and who approves what. Fit from text reads that text and proposes the ontology changes it supports: new classes, new properties, new relations. Each proposal quotes the sentence that supports it. The proposals wait in the suggestion inbox until a person accepts or dismisses them, so nothing changes your ontology on its own.
Fit from text works like search by meaning. You declare on a class which properties hold the text, and the platform keeps the proposals in step with your graph. A new or changed instance is read after the next commit is published.
The fit proposes ontology changes only. Extracting the facts of each text (the people, tools and dates) stays with you.
1. Commit the text
Section titled “1. Commit the text”Commit each text as an instance of a class, with the text in a string property. A transcript of 40,000 characters fits in one property. This example loads four short interviews in Turtle:
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .@prefix c: <https://example.org/class/> .@prefix e: <https://example.org/interview/> .@prefix p: <https://example.org/p/> .
e:jonas-berg a c:interview ; rdfs:label "Interview with Jonas Berg" ; p:transcript """Interviewer: How does a customer request reach your team?Jonas: Every request becomes a ticket in Deskflow, our ticket system. ...""" .curl -X POST "$LBB/v1/graph/import/rdf?format=turtle" \ -H "Authorization: Bearer $LBB_API_KEY" \ --data-binary @interviews.ttlJSON records work the same way: commit an Interview with a transcript
property. Documents from the SharePoint and Google Drive integrations
already carry a text property.
2. Preview what the fit reads
Section titled “2. Preview what the fit reads”The preview shows the fields the fit would read and the text of a few instances. It stores nothing and calls no model.
curl -X POST "$LBB/v1/ontology/fit-sources/preview" \ -H "Authorization: Bearer $LBB_API_KEY" -H 'Content-Type: application/json' \ --data '{"class": "https://example.org/class/interview", "from": ["transcript"]}'from takes the same paths as an embedding: a property name
(transcript), label, a prefixed name, a full IRI, or a path with one
link. Without from, the long text facts of the class are chosen.
Add "propose": true for a dry run. The models read the first part of up
to three instances, and every proposal comes back with the quote, the
support score and what the checks made of it. Nothing is filed. The dry run
waits at most 60 seconds for the models; an instance that has not finished
by then is left out, and truncated says so.
3. Declare a fit source
Section titled “3. Declare a fit source”In the console, open Review and click Suggest from text (also under Models → Ontology fit → From text). Pick the class and its text fields, write one sentence about the text, try it on 3 instances, and click Start reading. With the API:
curl -X PUT "$LBB/v1/ontology/fit-sources" \ -H "Authorization: Bearer $LBB_API_KEY" -H 'Content-Type: application/json' \ --data '{ "class": "https://example.org/class/interview", "from": ["transcript"], "context": "Interviews with employees about their work processes and the tools they use" }'context is one sentence about the text. The model reads it with every
part of every text.
With the TypeScript client:
import { LbbClient } from "@littlebigbrain/client";
const client = new LbbClient({ baseUrl: process.env.LBB_URL!, apiKey: process.env.LBB_API_KEY!,});
const dryRun = await client.ontology.fitSources.preview({ class: "https://example.org/class/interview", from: ["transcript"], propose: true,});await client.ontology.fitSources.declare({ class: "https://example.org/class/interview", from: ["transcript"], context: "Interviews with employees about their work processes and the tools they use",});With Python, client.ontology.fit_sources.declare(class_, from_=[...], context=...) does the same. Agents use the MCP tools lbb_fit_sources
and lbb_fit_sources_manage.
The platform now reads every interview. For each one:
- A reasoning model proposes changes for each part of about 40,000 characters, each with a quote from the text.
- Every quote is checked against the text. A proposal whose quote is not in the text is dropped.
- Every change is checked against your current ontology. Invalid changes and changes you have already are dropped.
- A decision model scores how well each quote supports its change. Weak support (below 0.5) is dropped.
- The kept proposals become suggestions. The same change from many interviews is one suggestion, with the number of interviews that support it and up to 20 quotes.
Check the progress:
curl "$LBB/v1/ontology/fit-sources?name=interview" -H "Authorization: Bearer $LBB_API_KEY"The status shows the instances read, the changed instances still to read,
the proposals kept and dropped per check, the suggestions filed, this
month’s spend and the last error. POST /v1/ontology/fit-sources/refresh?name=interview asks the platform to read
new instances now and returns at once; check the status again for the
progress.
4. Review the suggestions
Section titled “4. Review the suggestions”In the console, open Review. With the API, list the suggestions of the source:
curl "$LBB/v1/ontology/suggestions?origin_id=fit:interview" \ -H "Authorization: Bearer $LBB_API_KEY"Each suggestion shows the change, the number of interviews that support it, and the quotes. Accept the changes you want, edit one before you accept it, or dismiss it with a reason.
A dismissed change is not filed again. It reopens only when the interviews that support it reach twice the count it had when you dismissed it, and at least three more.
5. Accept
Section titled “5. Accept”curl -X POST "$LBB/v1/ontology/suggestions/accept?suggestion_id=sg_…" \ -H "Authorization: Bearer $LBB_API_KEY"Accepting applies the change to the ontology as it is now. New interviews keep adding support to the open suggestions.
Read one text or document
Section titled “Read one text or document”To try the fit on one text without a class, use Suggest from text in
the console, or call POST /v1/ontology/fit-text with pasted text:
curl -X POST "$LBB/v1/ontology/fit-text" \ -H "Authorization: Bearer $LBB_API_KEY" -H "Content-Type: application/json" \ -d '{"name": "meeting-notes", "text": "We track every support ticket on a shared board. …", "context": "Notes from a team meeting", "dry_run": true}'Or with an uploaded PDF. Parse it first with the Parse documents workflow, then give its SHA-256 and, if you like, the pages to read:
curl -X POST "$LBB/v1/ontology/fit-text" \ -H "Authorization: Bearer $LBB_API_KEY" -H "Content-Type: application/json" \ -d '{"name": "parts-catalogue", "document": "<sha256>", "pages": {"from": 1, "to": 20}, "context": "A parts catalogue with one sheet per part."}'The call runs the same checks as a fit source and returns every proposal
with its outcome. With dry_run: true it files nothing. Otherwise the kept
proposals go to the inbox under fit:<name>, each with its quote; for a
PDF also the page and the line the quote is on. One call reads at most
about 60,000 characters (16 parts) and takes about a minute and a half. A
longer text is cut after the first pages that fit, and the answer says
truncated: true and which pages it read. A file without parsed pages
gives 409 document_not_parsed.
Cost and limits
Section titled “Cost and limits”Each part of a text is one call to the reasoning model, and each text one
call to the decision model. The calls count against a monthly budget for
fit from text per stack (10 US dollars by default). At the limit the fit
stops with 429 fit_budget_exceeded until the next month. Fit from text
needs a Cloud plan.
Every model call is in the call log under Models, so you can check the proposals and the scores.