Large language models excel at synthesizing messy context, translating unstructured logs, and answering open-ended queries. However, they are fundamentally probabilistic. In production environments where physical infrastructure is on the line—such as high-voltage distribution networks, factory sub-stations, and thermal storage plants—probabilistic behavior can be a liability.
If an operator asks an operations assistant to summarize grid telemetry and suggest a load-shedding sequence, an LLM might hallucinate a safety threshold or confuse megawatt-hours with kilowatt-hours. In software engineering, this is a bug. In industrial facilities, this triggers breaker trips, equipment degradation, or violation of contractual peak-demand limits.
To build dependable tools for physical systems, you cannot let an LLM make raw control decisions or act as the primary validation layer. The solution is a hybrid architecture: deterministic, rule-based systems handle physics, state estimation, and safety limits, while the LLM acts strictly as an interface and context-aggregator.
The Failure Mode of Pure LLMs in Operations
LLMs operate over token distributions, not physical laws. Even with few-shot prompting and retrieval-augmented generation (RAG), three failure modes persist in industrial telemetry:
-
Numerical Drift and Hallucinated Units: A model can effortlessly read
480Vin one paragraph and output480 kWin the next when calculating phase load. - Silently Dropped Constraints: Prompts with complex nested conditions ("never shed Feeder 3 if Boiler 1 is running, unless Ambient Temperature exceeds 35°C") degrade in reliability as context lengths grow or when edge-case telemetry arrives.
- Non-Deterministic Tool Execution: When models are granted direct access to APIs via function calling, variations in temperature sampling or minor prompt mutations can cause them to skip a required safety pre-check before calling a dispatch endpoint.
In energy monitoring, these failures carry tangible costs. Exceeding contracted peak power capacity for even a fifteen-minute window can alter an industrial consumer's utility tariff for months.
Architecture: Rules as the Substrate, LLMs as the Interface
A robust architecture decouples the execution layer from the language layer. Instead of asking the model to monitor the plant, the plant's monitoring engine continuously evaluates deterministic rules, computes state summaries, and hands verified facts to the model.
[ Raw Sensors / PLC Telemetry ]
│
▼
┌──────────────────────────────┐
│ Deterministic Rule Engine │
│ - Physics validation │
│ - Threshold & rate checks │
│ - Hard interlocks & trips │
└──────────────┬───────────────┘
│
Validated State & Alerts
│
▼
┌──────────────────────────────┐
│ LLM Translation Layer │ ◄── [ Operator Natural Language Query ]
│ - Incident summarization │
│ - Log cross-referencing │
│ - Contextual explanation │
└──────────────┬───────────────┘
│
Proposed Action Plan
│
▼
┌──────────────────────────────┐
│ Action Firewall (Gatekeeper) │
│ - Schema validation │
│ - Safety envelope assertion │
└──────────────┬───────────────┘
│
[ Physical Dispatch / Actuator ]
In this model, the LLM has two roles:
- Downstream synthesis: Converting structured rule violations, raw time-series trends, and maintenance logs into clear status updates for human operators.
- Upstream proposal: Translating unstructured human requests ("Prep line 2 for peak-shaving this afternoon") into structured function calls.
Crucially, those function calls do not hit the physical systems directly. They pass through an Action Firewall—a deterministic validation service that evaluates proposals against hard engineering constraints.
Concrete Implementation: Power Load Thresholding
Consider an energy monitoring system where an operator wants an LLM assistant to draft load-shedding configurations during high-tariff periods. Below is a simplified Python pattern illustrating how deterministic assertions surround the LLM interaction.
from pydantic import BaseModel, Field, model_validator
from typing import List, Literal
# 1. Deterministic Domain Models with Hard Invariants
class LoadShedAction(BaseModel):
feeder_id: str
curtailment_kw: float = Field(gt=0, description="Must curtail positive kW")
priority: int = Field(ge=1, le=5)
class OperationalEnvelope(BaseModel):
max_total_curtailment_kw: float
protected_feeders: List[str]
class SheddingPlan(BaseModel):
actions: List[LoadShedAction]
def validate_safety(self, envelope: OperationalEnvelope) -> None:
total_kw = sum(a.curtailment_kw for a in self.actions)
if total_kw > envelope.max_total_curtailment_kw:
raise ValueError(
f"Total curtailment {total_kw}kW exceeds limit of "
f"{envelope.max_total_curtailment_kw}kW"
)
for action in self.actions:
if action.feeder_id in envelope.protected_feeders:
raise ValueError(f"Feeder {action.feeder_id} is protected and cannot be shed")
# 2. Gatekeeper: LLM Output Verification
def execute_llm_proposal(raw_llm_json: dict, envelope: OperationalEnvelope):
try:
# Step A: Validate syntactic structure
plan = SheddingPlan(**raw_llm_json)
# Step B: Assert physical and business rules deterministically
plan.validate_safety(envelope)
# Step C: If and only if rules pass, allow dispatch
print(f"Plan valid. Dispatching curtailment for {[a.feeder_id for a in plan.actions]}.")
return {"status": "applied", "plan": plan.model_dump()}
except ValueError as e:
# The system rejects the action deterministically before state change
print(f"Safety violation rejected by rule engine: {str(e)}")
return {"status": "rejected", "reason": str(e)}
# Example Scenario:
envelope = OperationalEnvelope(
max_total_curtailment_kw=500.0,
protected_feeders=["FEEDER_CRITICAL_COOLING", "FEEDER_HVAC_HQ"]
)
# LLM erroneously generates a plan that targets a protected cooling feeder
llm_generated_output = {
"actions": [
{"feeder_id": "FEEDER_CRITICAL_COOLING", "curtailment_kw": 120.0, "priority": 2},
{"feeder_id": "FEEDER_ASSEMBLY_B", "curtailment_kw": 150.0, "priority": 1}
]
}
result = execute_llm_proposal(llm_generated_output, envelope)
# Output: Safety violation rejected by rule engine: Feeder FEEDER_CRITICAL_COOLING is protected and cannot be shed
The LLM can write text, parse emails from the grid operator, and construct JSON payloads. But the Python layer ensures no execution occurs if an invariant is broken.
Evaluation and Safety Invariants
When testing software that controls physical assets, unit testing prompts is insufficient. You need distinct test suites for both halves of the hybrid system:
1. Rule Engine Test Suite
The rule engine should be evaluated with traditional property-based testing. Use tools like hypothesis to fuzz the boundary conditions: negative loads, sudden frequency drops, out-of-order time-series packets, and missing sensor values. Verify that safety interlocks trigger under all fault states without relying on any machine learning model.
2. LLM Interface Evaluation
Instead of evaluating the LLM for general conversational capability, score it on compliance and recovery:
- Rejection Recovery: When the Action Firewall rejects a plan, does the model take the error string and output a valid alternative, or does it loop into repeated invalid outputs?
- Information Extraction Precision: Given real telemetry logs, does the model accurately report out-of-bound variables without skipping entries?
- Schema Adherence: What percentage of LLM responses adhere strictly to the target JSON schema on the first attempt?
If the LLM fails, the system must fail safe. For instance, if the LLM service suffers an outage or returns invalid JSON three times consecutively, the monitoring system falls back to predefined, deterministic heuristic tables for load management.
Key takeaways
- Separate translation from execution: Use the LLM to ingest context, query logs, and draft plans, but keep it isolated from direct dispatch APIs.
- Enforce an Action Firewall: Every model output that could alter system state must pass through deterministic schema and physics validations before execution.
- Physics over probabilities: Never rely on system prompts or RAG to guarantee hard thresholds; token probabilities cannot replace mathematical assertions.
- Design for deterministic fallbacks: If the generative layer produces invalid outputs or becomes unreachable, the rule engine must maintain baseline monitoring and safety operations autonomously.
Top comments (0)