Agent, harness, skills, hooks: four concepts people mix up

AI agents are all anyone talks about right now, but four distinct concepts often get blurred together: the agent, the harness that orchestrates it, skills loaded on demand, and hooks triggered on events. Separating them clearly helps clarify what's probabilistic and what's deterministic in an agentic system, and avoids costly design mistakes.
┌──────────────────────── harness (deterministic) ────────────────────────┐
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ agent (loop, probabilistic) │ │
│ │ │ │
│ │ observe ──▶ decide ──▶ act ──▶ observe the result │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ skill loaded if the model judges it useful (probabilistic) │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ hook ── runs systematically on an event (deterministic) │
└───────────────────────────────────────────────────────────────────────────┘
The agent: the loop
The agent is the loop itself: the model observes a context, decides on an action (respond, call a tool, stop), observes the result, and starts again. This loop is probabilistic by nature: given the same context, the model can choose different paths. That property is what makes the agent useful on open-ended tasks, and what makes it unsuited to tasks that require a strict guarantee.
The harness: what orchestrates the agent
The harness is the software layer around the agent: it manages the context (what information the model can see), the format of available tools, memory across turns, recovery after errors. Claude Code, for instance, is a harness: it doesn't "think" on the model's behalf, but it determines what the model can see and do at each step.
The choice of harness has more impact on an agent's perceived quality than the choice of model itself: an excellent model that's poorly tooled produces mediocre results, while a well-designed harness can compensate for some of the model's limits by feeding it exactly the context it needs, at the right moment.
Skills: probabilistic, loaded on demand
A skill is a capability the agent can choose to load when it judges it relevant. The model decides: nothing guarantees that an available skill will actually be used for a given task. It's a probabilistic mechanism, just like the rest of the agent's reasoning.
That probabilistic nature isn't a flaw, it's a deliberate feature: it lets you keep dozens of skills available without systematically overloading the agent's context with instructions that won't help the current task.
Hooks: deterministic, triggered on events
A hook, by contrast, runs systematically when a specific event occurs (before a tool call, after a response, on action failure). It doesn't depend on the model's judgment: it's plain, predictable code that runs every time the condition is met, no exceptions, and no say for the model in the matter.
The four concepts, in one table
| Concept | Nature | Who decides it triggers | Concrete example |
|---|---|---|---|
| Agent | Probabilistic | The model, on every turn of the loop | The reasoning that chooses to call a search tool over another one |
| Harness | Deterministic | The code wrapped around the agent | Claude Code deciding which files are visible in the context |
| Skill | Probabilistic | The model, if it judges the skill relevant | A code-review skill, loaded only if the task looks like a review |
| Hook | Deterministic | A specific event, with no model judgment | A hook that systematically blocks an rm -rf before execution |
The table is best read through its third column: whenever a guarantee must never depend on the model's judgment, only the "deterministic" column (harness or hook) can provide it. A skill, however well written, remains by nature an invitation, never an obligation.
Why this distinction matters
Whenever you need a guarantee, a systematic validation, or a safety rule that must never be bypassed, a hook is the right tool: it's deterministic. Whenever you need to extend the agent's capabilities without permanently weighing it down, a skill is the right tool: it's only loaded if the agent needs it.
Confusing the two leads to fragile architectures, where you expect a probabilistic mechanism (a skill) to provide a guarantee it cannot offer, or where you make rigid (via hooks) something that should stay adaptive. I've seen both mistakes in practice: a critical security rule entrusted to a skill, which worked most of the time but not consistently, and a hook so rigid it blocked legitimate cases its author hadn't anticipated. In both cases, the problem wasn't the implementation, it was picking the wrong mechanism in the first place.