Semogram Docs
Forecasting and predictions

Your first equipment prediction

Build a known equipment source, publish its evidence query and run a failure-risk prediction

You need a Semogram account, workspace access, a project and permission to manage definitions, bindings, queries and forecasters. The deployment needs forecasting, a usable model and the prediction workflow runtime. Use a dedicated test Postgres database reachable by Semogram, with a database user that can read the fixture. This example includes the setup; it assumes no existing ontology or evidence query.

MCP examples here assume a project-scoped connection. If using the workspace endpoint, add the selected projectId from project_list to project tool calls and follow that endpoint’s discovered schema.

What you will build

Two synthetic equipment records supply an ontology query. The query selects one equipment identifier. A probability forecaster asks whether that equipment will have an unplanned mechanical failure causing at least one hour of downtime over seven days. You will run P-101, inspect the saved evidence and learn how to record a real outcome later.

IdentifierMeaning
public.forecast_demo_equipmentPhysical table you create in the test database
maintenance_demo.equipmentWorkspace endpoint name you choose in Semogram
https://example.com/maintenance#EquipmentClass defined in the model file
https://example.com/equipment/P-101Stable entity identifier in the source row
P-101Value of equipmentId and subject passed to this query
equipment-failure-riskForecaster slug created in this project

P-101 works because the query explicitly matches the equipmentId property to subject_ref. Do not interchange that subject value with the entity IRI or a database UUID.

1. Create a known source

In your database SQL client, run the fixture below. It is synthetic connection-test data, not a set of measured failure rates. Replace observation times with the actual time your test measurements represent; merely editing a timestamp does not make an old measurement fresh.

Source fixture
CREATE TABLE public.forecast_demo_equipment (
  entity_id text PRIMARY KEY,
  equipment_id text NOT NULL,
  vibration_mm_s double precision NOT NULL,
  temperature_c double precision NOT NULL,
  days_since_service integer NOT NULL,
  observed_at text NOT NULL
);
INSERT INTO public.forecast_demo_equipment VALUES
 ('https://example.com/equipment/P-101', 'P-101', 7.2, 86.0, 180, '2026-10-05T08:00:00Z'),
 ('https://example.com/equipment/P-102', 'P-102', 2.1, 62.0, 30, '2026-10-05T08:00:00Z');
SELECT * FROM public.forecast_demo_equipment ORDER BY equipment_id;

Install the workspace Postgres read capability (@craven/postgres) through Plugins → Explore. Fill Host, Port (usually 5432), Database, User, protected Password and Ssl. The database user needs SELECT on public.forecast_demo_equipment. Check the connection. The installation guide explains additional options; all fields needed for this fixture are stated here.

Create a workspace Data Endpoint: namespace maintenance_demo, name equipment, direction Ingress, the installed Postgres read capability, source_stream contract, target schema public and table forecast_demo_equipment. Save and inspect both rows. Keep its endpoint UUID for technical calls. Credentials belong to the installation, not the endpoint target or assistant prompt.

2. Define equipment terms

Create a project ontology definition named maintenance-demo, namespace https://example.com/maintenance#, model entrypoint model.ttl, no shape entrypoints or imports. Use this complete file:

model.ttl
@prefix ex: <https://example.com/maintenance#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
ex:Equipment a owl:Class ; rdfs:label "Equipment" .
ex:equipmentId a owl:DatatypeProperty ; rdfs:domain ex:Equipment ; rdfs:range xsd:string .
ex:vibrationMmS a owl:DatatypeProperty ; rdfs:domain ex:Equipment ; rdfs:range xsd:double .
ex:temperatureC a owl:DatatypeProperty ; rdfs:domain ex:Equipment ; rdfs:range xsd:double .
ex:daysSinceService a owl:DatatypeProperty ; rdfs:domain ex:Equipment ; rdfs:range xsd:integer .
ex:observedAt a owl:DatatypeProperty ; rdfs:domain ex:Equipment ; rdfs:range xsd:string .

In Ontology → Definitions, ask the authoring assistant to prepare that exact model and manifest, review validation, then save. A technical caller can supply the complete definition body to ontology_create with projectId and a unique idempotencyKey. The supported public ontology API is POST /api/v1/projects/PROJECT_UUID/ontology/definitions with that body, an ontologies:write key and Idempotency-Key header. This API creates the model, not a forecaster.

Inspect the compiled project package UUID and numeric version. They differ from the definition asset UUID and saved-version UUID. Use the actual package/version below; compilation creates structure, not equipment records.

3. Bind the source fields

Open Ontology → Bindings and create six Active Virtual bindings on the compiled package/version and maintenance_demo.equipment endpoint. Use priority 100, default disabled and the exact full term identifiers. The resolution values belong in the advanced Resolution field.

Full term identifierApplies toExpected valuesResolution
https://example.com/maintenance#EquipmentClassMany{"entity_id_field":"entity_id"}
https://example.com/maintenance#equipmentIdPropertyOne{"field":"equipment_id"}
https://example.com/maintenance#vibrationMmSPropertyOne{"field":"vibration_mm_s"}
https://example.com/maintenance#temperatureCPropertyOne{"field":"temperature_c"}
https://example.com/maintenance#daysSinceServicePropertyOne{"field":"days_since_service"}
https://example.com/maintenance#observedAtPropertyOne{"field":"observed_at"}

For this test, leave access policy empty only if intended readers may read these values. For technical authoring, call ontology_read_binding_create with a binding object containing ontologyPackageId, ontologyPackageVersion, termRef, termIri, termKind, kind virtual, dataEndpointId, status active, cardinality and resolution, plus an outer idempotencyKey. Repeat for all six terms. Draft bindings are not executable.

4. Publish the evidence query

In Ontology → Queries, create Equipment forecast evidence using the complete YAML below. Replace the compiled package UUID and version. Validate, execute a preview with subject_ref P-101, horizon 7d and params an empty object, then publish a release. Keep the query UUID and release identity.

Equipment evidence query
query_definition:
  name: Equipment forecast evidence
  slug: equipment-forecast-evidence
  ontology_package_id: <COMPILED_PACKAGE_UUID>
  ontology_package_version: 1
  target:
    kind: virtual
  input_schema:
    type: object
    properties:
      subject_ref: { type: string }
      horizon: { type: [string, 'null'] }
      params: { type: object }
    required: [subject_ref]
    additionalProperties: true
  root:
    term_ref: https://example.com/maintenance#Equipment
    identity:
      term_ref: https://example.com/maintenance#equipmentId
      input: subject_ref
    cardinality: many
  output_schema:
    type: object
    properties:
      equipmentId: { type: string }
      vibrationMmS: { type: number }
      temperatureC: { type: number }
      daysSinceService: { type: integer }
      observedAt: { type: string }
    required: [equipmentId, vibrationMmS, temperatureC, daysSinceService, observedAt]
    additionalProperties: false
  output_mapping:
    equipmentId: { term_ref: 'https://example.com/maintenance#equipmentId' }
    vibrationMmS: { term_ref: 'https://example.com/maintenance#vibrationMmS' }
    temperatureC: { term_ref: 'https://example.com/maintenance#temperatureC' }
    daysSinceService: { term_ref: 'https://example.com/maintenance#daysSinceService' }
    observedAt: { term_ref: 'https://example.com/maintenance#observedAt' }
  policy:
    limit: 10

Technical callers can use ontology_query_create with name and content (the YAML string), ontology_query_validate, then ontology_query_publish with queryId, expectedVersionId and a unique idempotencyKey. Publication requires the actual saved version ID; an invented ID is not a substitute for validation. The file is downloadable as equipment-evidence.yaml.

The P-101 preview should return exactly one row:

Expected evidence row
{
  "equipmentId": "P-101",
  "vibrationMmS": 7.2,
  "temperatureC": 86,
  "daysSinceService": 180,
  "observedAt": "2026-10-05T08:00:00Z"
}

P-102 must not appear. An empty result indicates a subject/binding/source problem, not a healthy pump. Check diagnostics and source snapshots before continuing.

5. Create the forecaster

The prompt defines the event. It does not embed a desired probability:

Forecaster prompt
Estimate the probability that equipment {{subject_ref}} experiences an unplanned mechanical failure causing at least one hour of downtime during {{horizon}}. A preventive service visit is not a failure. Use only the supplied evidence; explain its age, missing history and limitations. Do not describe this synthetic fixture as measured failure statistics. Return probability, confidence and rationale in the output schema.

Evidence:
{{evidence_json}}
Assistant prompt
Prepare Equipment failure risk using the published Equipment forecast evidence query in this project. Predict an unplanned mechanical failure causing at least one hour of downtime within 7d. Use the prompt above, probability output, separate confidence, single-call execution and manual outcome evaluation. Show the proposed query, event and settings before creating.

The creation assistant prepares a reviewable operator draft. Inspect its derived schemas and defaults; use the edit form for advanced schema/budget changes after creation.

Open project Predictions → Forecasters → New forecaster and its manual option. Name: Equipment failure risk. What does it predict?: A probability. Evidence: Equipment forecast evidence. Horizon: 7d. Under Advanced, enter the prompt above. Review and Create forecaster.

The creation form derives its schemas and single_call configuration. To match the strict technical example, open the forecaster Edit page afterward: set Input schema and Output schema from the MCP payload, Execution config to the shown budget, Probability output path to $.probability, Confidence path to $.confidence and manual Outcome resolution. Save and inspect the new version.

Use forecaster_create in the authenticated project. Replace the query UUID and key. Workspace/project scope comes from the connection. Omit modelLabel to use the deployment's configured default model.

MCP tool call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "forecaster_create",
    "arguments": {
      "slug": "equipment-failure-risk",
      "displayName": "Equipment failure risk",
      "description": "Unplanned mechanical failure causing at least one hour of downtime within the forecast window",
      "forecasterKind": "equipment_failure",
      "forecastKind": "probability",
      "queryDefinitionId": "<PUBLISHED_EVIDENCE_QUERY_UUID>",
      "promptTemplate": "Estimate the probability that equipment {{subject_ref}} experiences an unplanned mechanical failure causing at least one hour of downtime during {{horizon}}. A preventive service visit is not a failure. Use only the supplied evidence; explain its age, missing history and limitations. Do not describe this synthetic fixture as measured failure statistics. Return probability, confidence and rationale in the output schema.\n\nEvidence:\n{{evidence_json}}",
      "inputSchema": {
        "type": "object",
        "properties": {
          "subject_ref": {
            "type": "string"
          },
          "horizon": {
            "type": "string"
          },
          "params": {
            "type": "object"
          }
        },
        "required": [
          "subject_ref",
          "horizon",
          "params"
        ],
        "additionalProperties": false
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "probability": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "confidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "rationale": {
            "type": "string"
          }
        },
        "required": [
          "probability",
          "confidence",
          "rationale"
        ],
        "additionalProperties": false
      },
      "executionConfig": {
        "mode": "single_call",
        "budget": {
          "maxDurationMs": 60000,
          "maxTotalTokens": 20000,
          "maxExternalCalls": 0
        }
      },
      "defaultHorizon": "7d",
      "defaultParams": {},
      "confidencePath": "$.confidence",
      "probabilityPath": "$.probability",
      "outcomeResolution": {
        "kind": "manual"
      },
      "evaluationPolicy": {
        "kind": "manual"
      },
      "tags": [
        "equipment"
      ],
      "status": "active",
      "idempotencyKey": "<UNIQUE_CREATE_KEY>"
    }
  }
}

Creation publishes the first executable forecaster version and pins the evidence query's latest published release. There is no additional standalone forecaster publish action. Inspect the saved forecaster's version, forecast kind, probability path and pinned query release before running.

6. Run once

Assistant prompt
Run Equipment failure risk for subject P-101 over the next seven days. Set the evaluation date to seven days from this run, not the illustrative fixed date in the docs. Show the selected forecaster version and pinned evidence release before running.

An external connected assistant can use forecast_run. The dedicated in-app forecaster creation assistant prepares definitions; use the Run page to invoke an existing one.

Open Predictions → Run prediction. Choose Equipment failure risk, enter Subject P-101, Horizon 7d and inspect the derived evaluation date. Use empty parameters. Confirm Run prediction and open its record.

MCP tool call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "forecast_run",
    "arguments": {
      "forecasterSlug": "equipment-failure-risk",
      "subjectRef": "P-101",
      "horizon": "7d",
      "horizonEndsAt": "2027-01-08T08:00:00Z",
      "params": {},
      "idempotencyKey": "<UNIQUE_RUN_KEY>"
    }
  }
}

Use a future UTC horizonEndsAt consistent with the seven-day window. The fixed date in serialized examples is illustrative; replace it with seven days after your actual run. The horizon label alone does not set the direct MCP evaluation date. The UI can derive it from a duration.

7. Inspect the completed result

Open the returned prediction. It may initially be Queued or Running. Wait for its own Completed state, then inspect subject, horizon end, forecaster version, query release, evidence rows and snapshots, prompt, output, probability, confidence, warnings, usage and cost availability. Use prediction_get with predictionId to read it through MCP.

The model's probability is not predetermined. Passing this fixture means the right evidence reached a schema-valid run. It does not mean P-101's true seven-day risk has been measured. No training history or independently validated failure relationship is present in these two rows.

8. Record what actually happened

Retain the real observation record for the defined event. For a completed probability prediction, an occurrence can be recorded after invocation and before the window ends. “Did not occur” requires that the window has ended. Missing monitoring is Unknown, not Did not occur.

In the prediction's Outcome panel, select the appropriate outcome, actual observation time and notes, then Record evaluation. Through MCP, use prediction_evaluation_create with predictionId, outcomeState, observedAt, evidenceAssertionIds, evaluatorKind human, notes and a unique idempotencyKey. Use actual project assertion IDs when linking evidence; never the fixture's invented references. An observation cannot be future-dated. Evaluations are immutable versions; record a later evaluation to correct an observation.

After real observations exist, inspect the forecaster evaluation report. A single outcome is not a reliability study. The platform records scores; it does not automatically retrain the forecaster.