The one idea
An agent is not the model - it is a loop. And the only thing we swap is the decision box.
In the previous chapter we fixed the world as a model - with a goal, reflexes and rules. Now we turn to the actor that decides inside that world.
The one idea: An agent is not the model. An agent is a loop - perception → decision → action - and the only thing we swap is the decision box. We build one world and drop four different brains into it, one after another. Only then do you see what “AI” actually means.
We build an ant colony that collects sugar - inspired by the old learning game AntMe!, but in the browser and with one decisive twist: the ant's brain is a swappable function.
decide(perception) → action
Four implementations of this one function:
| Stage | Brain | What you learn about agents |
|---|---|---|
| 1 | Hardcode (fixed rules) | The skeleton: perceive → decide → act. The baseline. |
| 2 | Learning network (Q-learning) | The machine finds the rules itself from reward. |
| 3 | LLM steers | Language as decision. Latency. Ghost-calls. |
| 4 | LLM + skills + memory | When an LLM actually beats the hardcode. |
Same world, same loop. Only the box changes. That is the whole trick - and the whole lesson.
The architecture that carries everything
Before a line of brain exists, we define the contract between world and agent. The world must never know which brain is driving. Three functions:
// 1. The world turns the ant's state into a perception.
perceive(ant, world) → percept
// 2. The BRAIN picks a decision from the perception. (swappable!)
brain.decide(percept) → decision // navigation, optionally a marker
// 3. The world executes the decision and returns reward events.
applyAction(ant, decision, world, percept) → { picked, delivered }
As long as every brain fulfils decide, the world runs unchanged. This exact
separation reappears in real agent systems: the environment (tools, data, state) is
cleanly decoupled from the decider (rule, model, LLM).
The action vocabulary
We decide at the behaviour level, not the “muscle level”. That keeps the state space small enough to learn and readable enough for an LLM:
const ACTIONS = ["ERKUNDE", "ZUM_ZUCKER", "FOLGE_SPUR", "ZUM_BAU"];
Design decision with consequences: Picking up and dropping off are reflexes of the world (they happen automatically on contact), not learned actions. If the agent had to learn “PICK UP” pixel-perfectly itself, credit assignment explodes and nothing converges in a live demo. What gets learned is pure navigation - which maps 1:1 to the hardcode rules. This separates innate reflexes from learned strategy.