An active-inference agent needs four kinds of states, not one. If you conflate them, your generative model quietly stops being a model of the thing it is supposed to steer. This post is the engineer's cut of the decomposition, with the parts that are math kept separate from the parts that are your choice.
The four classes
Following the Parr, Pezzulo and Friston formulation of active inference over a partially observed Markov decision process (Class E), the state of a coupled agent-plus-environment system is split four ways:
- Internal states live inside the agent. They carry the agent's beliefs, its parameters, the sufficient statistics of its posterior over what is out there.
- External states live outside the agent. The agent never sees them directly. In the Cell Lab these are the 216 hidden states of the service cell (Class C); in the Precision Lab, the true wall geometry.
- Sensory states are the interface that carries information from external into internal. Wall sensors, echo returns, log lines, blood pressure, whatever your build treats as observation.
- Active states are the interface that carries information from internal back out. Moves, dial changes, API calls, drug doses, whatever your build treats as an action channel.
Sensory and active states together form the Markov blanket: the two-sided membrane that decouples inside from outside. Internal states influence external states only by moving active states. External states influence internal states only by moving sensory states. That is the structural claim, and it is the whole reason the math factorises.
What the split buys you as a builder
Once the four classes are separated, three engineering moves get much cleaner (Class C). First, you can write a generative model P(o, s) that maps sensory observations o to hidden causes s without having to talk about actions in the same breath. Second, you can write a policy prior P(pi) over sequences of active states and score policies by expected free energy, keeping perception and control in the same currency. Third, when a system misbehaves, you can ask a diagnostic question with a real answer: which side of the blanket broke. Was it the sensory channel (bad observations), the internal model (bad beliefs), or the active channel (bad actuation)?
In the Cell Lab this shows up concretely. The agent's posterior over 216 hidden cell states updates only from a small sensory vector, and it steers only through a small active vector (Class C). When RecoveryScore drops in one disturbance family and holds in another, you have a real localisation problem to work on, not a vibes problem.
Where the decomposition is a modeling choice
Here is the honest part. The four-way split is a modeling choice about where you draw the blanket, not a fact printed on the substrate. In a running Kubernetes cluster, is the sidecar's outbound HTTP call an active state (the agent is acting on the world) or an internal computation (the agent is thinking, and the world happens to see it)? In a person, is heart rate a sensory state of the brain or an internal state of the body? Both framings can be self-consistent. They yield different generative models and different policies.
This is why UNI publishes the labs with their state partitions declared up front, and why the Cell Lab's fences say the agent never sees the hidden state (Class C). The partition is part of the experiment, not a given.
Two common mistakes
The first is smuggling external states into the generative model. If your agent's posterior is conditioned on something the deployed agent will not actually observe at run time, you have a leaky blanket and your offline numbers will not survive contact with the runtime. The second is treating active states as free. Every action carries an expected-free-energy cost through its own predicted consequences. An active-inference agent that never pays for its actions is a planner in disguise, not an inference agent.
Both mistakes are easy to make and easy to catch: write out the four sets explicitly, verify that the sensory set is exactly what the runtime hands you, and verify that the active set is exactly what the runtime lets you do. If the sets do not match the substrate, the model does not match the substrate.
This is a working hypothesis on an attainable path toward General Natural Intelligence: a natural, active-inference approach whose evidence is growing, evidence-classed, and tested in the open. Do not take the framing on faith. Test the build, inspect the gates, and help us find where it fails. Our current transparency posture is documented at /transparency.