cd /news/ai-agents/air-gapped-rig-edge-witsml-telemetry… · home › topics › ai-agents › article
[ARTICLE · art-164291] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

Air-Gapped Rig-Edge WITSML Telemetry with Local Small Language Models (SLMs)

A drilling engineer built an air-gapped edge intelligence stack that runs deterministic physics filters and quantized small language models (7B or 3B, via Ollama or llama.cpp) directly on rig-site hardware to triage WITSML/WITS telemetry, avoiding the 600–1200 ms satellite round-trip latency of cloud inference. The two-tier design uses a Rust/Python physics worker for flow-differential and standpipe-pressure checks, then passes a structured JSON context window to a local SLM for sub-second anomaly triage and root-cause classification, with asynchronous delta sync to headquarters only when connectivity allows.

by read5 min views2 publishedNov 5, 2026

Originally published with interactive math formulas and diagrams at eng.kcklayton.com

Drilling rigs—whether stationed offshore in deepwater or operating across remote onshore basins—share a common operational reality: high-latency, bandwidth-constrained, and intermittent satellite connectivity (VSAT).

Round-trip satellite pings routinely exceed $600\text{ to }1200\text{ ms}$, with atmospheric attenuation or antenna line-of-sight blockage causing frequent dropouts. When a high-pressure gas influx (kick) enters the wellbore, or when a bottom-hole assembly (BHA) experiences catastrophic stick-slip oscillation, seconds count. Routing real-time sensor telemetry to a remote cloud datacenter for LLM inference or anomaly classification introduces unacceptable operational latency and single-point-of-failure exposure.

To solve this, our drilling architecture decouples real-time rig surveillance into an Air-Gapped Edge Intelligence Stack running local deterministic filters and quantized Small Language Models (SLMs) directly on rig-site hardware.

Modern drilling rigs generate high-frequency telemetry across dozens of channels via the WITSML (Wellsite Information Transfer Standard Markup Language) and WITS (Wellsite Information Transfer Specification) standards:

flowchart TD
    subgraph RigFloor["Rig Floor & PWD Instrumentation"]
        Sensors["Rig Sensors (Flow, SPP, Pit, Hookload)"]
        PWD["Downhole MWD / PWD Telemetry"]
    end

    subgraph RigEdge["Edge Server (Rig Doghouse / Rig Server Room)"]
        WITSMLAgent["WITSML Edge Agent<br/>(1-sec Poller & In-Memory Ring Buffer)"]
        MathEngine["Deterministic Physics Filters<br/>(Flow In/Out Differential, Pit Rate)"]
        LocalSLM["Local SLM Inference Engine<br/>(Ollama / llama.cpp - Qwen / Mistral)"]
        RigDisplay["Local Rig Doghouse Alarm & HMI"]
    end

    subgraph RemoteCloud["Corporate Headquarters / Real-Time Operations Center (RTOC)"]
        CloudMesh["Event-Driven Telemetry Mesh"]
        RemoteDashboard["Engineering Dashboard"]
    end

    Sensors -->|WITS / WITSML| WITSMLAgent
    PWD -->|Mud Pulse / EM| WITSMLAgent
    WITSMLAgent --> MathEngine
    MathEngine -->|Anomaly Context Window| LocalSLM
    LocalSLM -->|Sub-second Triage & Root Cause| RigDisplay
    WITSMLAgent -.->|Async Delta Sync via VSAT (When Online)| CloudMesh
    CloudMesh -.-> RemoteDashboard

Language models should never replace basic physics calculations. Calculating flow differential ($\Delta Q = Q_{\text{out}} - Q_{\text{in}}$) or standpipe pressure derivatives ($\frac{dP}{dt}$) requires deterministic arithmetic, not probabilistic token generation.

The edge agent runs a two-tier architecture:

The witsml-edge-agent maintains a rolling in-memory ring buffer (defaulting to 300 seconds of 1-second records). A high-speed Rust/Python physics worker evaluates:

When Tier 1 triggers an anomaly condition, it compiles a structured JSON context payload capturing the pre-event baseline, trigger metrics, current rig state (drilling, tripping, circulating, reaming), and recent downhole events.

This payload is dispatched via localhost IPC to ai-gateway-sentinel, which interfaces directly with an embedded Ollama or llama.cpp instance running a quantized $7\text{B}$ or $3\text{B}$ parameter model (e.g., mistral-7b-instruct-q4_K_M or qwen2.5-coder-7b).

Here is how the edge agent structures the telemetry window and queries the local edge engine:

import numpy as np
from dataclasses import dataclass
from typing import List, Optional
import httpx

@dataclass
class TelemetryPoint:
    timestamp: float
    depth_ft: float
    rop_fph: float
    spp_psi: float
    flow_out_pct: float
    pit_total_bbl: float
    pumps_active: bool

class RigEdgeAnomalyDetector:
    def __init__(self, ollama_url: str = "http://127.0.0.1:11434"):
        self.buffer: List[TelemetryPoint] = []
        self.max_buffer_size = 300
        self.ollama_url = ollama_url
        self.anomaly_cooldown = 0

    def push(self, point: TelemetryPoint) -> Optional[dict]:
        self.buffer.append(point)
        if len(self.buffer) > self.max_buffer_size:
            self.buffer.pop(0)

        if len(self.buffer) < 30:
            return None

        recent = self.buffer[-5:]
        baseline = self.buffer[-30:-5]

        avg_baseline_pit = np.mean([p.pit_total_bbl for p in baseline])
        current_pit = recent[-1].pit_total_bbl
        pit_gain = current_pit - avg_baseline_pit

        flow_anomaly = (not recent[-1].pumps_active) and (recent[-1].flow_out_pct > 3.0)
        kick_indicator = pit_gain > 10.0

        if (flow_anomaly or kick_indicator) and self.anomaly_cooldown == 0:
            self.anomaly_cooldown = 60 # Cooldown to avoid prompt flooding
            return self._triage_with_local_slm(point, pit_gain, flow_anomaly)

        if self.anomaly_cooldown > 0:
            self.anomaly_cooldown -= 1

        return None

    def _triage_with_local_slm(self, pt: TelemetryPoint, pit_gain: float, flow_anomaly: bool) -> dict:
        prompt = f"""[RIG ALARM TRIAGE - HIGH PRIORITY]
You are a senior drilling superintendent and well control advisor running on an edge rig computer.
Current Telemetry:
- Hole Depth: {pt.depth_ft:.1f} ft
- Standpipe Pressure: {pt.spp_psi:.0f} psi
- Pumps Active: {pt.pumps_active}
- Flow Out: {pt.flow_out_pct:.1f}%
- Total Pit Gain: {pt.pit_gain:.1f} bbl
- Flow Anomaly Flag: {flow_anomaly}

Provide a concise, 3-bullet assessment:
1. Probable Root Cause (e.g., Formation Influx vs. Pit Transfer vs. Sensor Drift)
2. Immediate Verification Step for Driller (e.g., Space out and perform flow check)
3. Well Control Level (Green / Yellow / Red Alert)
Format response as strictly actionable guidance for the rig crew."""

        try:
            with httpx.Client(timeout=4.0) as client:
                res = client.post(
                    f"{self.ollama_url}/api/generate",
                    json={"model": "mistral:7b-instruct-q4_K_M", "prompt": prompt, "stream": False}
                )
                if res.status_code == 200:
                    return {"status": "ALERT", "assessment": res.json().get("response", "")}
        except Exception as e:
            return {"status": "ALERT", "assessment": "LOCAL SLM TIMEOUT - EXECUTE FLOW CHECK IMMEDIATELY"}
        return {"status": "ALERT", "assessment": "UNVERIFIED ANOMALY - INITIATE FLOW CHECK"}

Testing deployed on an industrial fanless rig-floor edge PC (Intel Core i7-12700E, 32GB DDR5, running Ubuntu Core 24.04 LTS):

Model / Quantization Parameter Size Memory Footprint Edge Inference Latency Deterministic Filter Latency Cloud Round-Trip (VSAT)
Deterministic Rule Filter N/A $< 40\text{ MB}$ $0.4\text{ ms}$ Baseline N/A
Qwen 2.5 3B (Q4_K_M) $3.1\text{B}$ $1.9\text{ GB}$ $210\text{ ms}$ $+0.4\text{ ms}$ $1,800\text{ ms}$
Mistral 7B Instruct (Q4_K_M) $7.2\text{B}$ $4.4\text{ GB}$ $490\text{ ms}$ $+0.4\text{ ms}$ $2,100\text{ ms}$
Llama 3.1 8B (Q4_K_M) $8.0\text{B}$ $4.9\text{ GB}$ $580\text{ ms}$ $+0.4\text{ ms}$ $2,300\text{ ms}$

By running locally:

The witsml-edge-agent and ai-gateway-sentinel work alongside our kill-sheet-calculations library. When a kick is verified, the edge agent can automatically push shut-in drillpipe pressure (SIDPP), shut-in casing pressure (SICP), and pit volume gain into the kill calculation engine, rendering a fully populated, IADC-compliant kill sheet within seconds of well shut-in.

── more in #ai-agents 4 stories · sorted by recency
── more on @ollama 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/air-gapped-rig-edge-…] indexed:0 read:5min 2026-11-05 · —