Calafia blog

🧩 What is an agent composition?

Ask what an agent is and you usually get an answer about the model. It runs on Claude, it runs on Gemini. That is one part, and it is rarely the part that decides whether the thing is useful.

A working agent is a goal plus a set of choices underneath the goal. The goal is the sentence you wrote: tell me when a campsite opens up at Doheny. The choices are everything the runtime needs to settle before it can carry that sentence out — and they are choices, which means they could have gone the other way, which means they are worth understanding.

We call the set of them a composition.

The parts

Memory is what the agent knows from its own earlier runs. The interesting half is not storage, it is ranking: which of last month's notes are pulled into today's context. Keyword ranking finds notes that share words with the goal. Semantic ranking finds notes that mean something similar. A hosted extraction service like mem0 distills notes into facts before storing them. Same history, different selection, different answer.

Planning is the scaffold it reasons inside. Decide a step, look, decide the next — the reason-and-act loop, adaptable, and prone to wandering. Or write the plan first and work it — steadier, and prone to finishing a plan whose premise stopped being true. Neither is better. They fail in opposite directions.

Retrieval is what gets handed to the run before it starts, as opposed to what the agent goes and fetches. Handing an agent its own recent run history stops it re-reporting a finding it already sent. The cost is context: everything retrieved competes for the same window as the goal and the tool descriptions.

State is the working note the agent leaves for its next self. Carrying it forward buys continuity — an agent that can track a value across days rather than rediscovering it. It costs you error propagation, because a wrong number in a carried note travels forward until something contradicts it.

Guardrails are the limits it runs inside, and the only word that matters is enforced. Every agent here is metered per tool call and stopped by a budget cap rather than warned about one. That is what makes an agent safe to leave alone: the worst case is bounded before it starts.

The model is the reasoning engine, chosen per agent and priced per run. Worth knowing: the expensive step is usually not the frequent step. One hard step can dominate a bill while most calls are routine.

Tools decide whether an answer is grounded or generated. An agent with a real adapter for a site reads that site. An agent without one writes something plausible about it. On the page those two outputs look identical.

Frameworks are the harness the agent's code lives in — the thing that owns its loop, its tool wiring and its state between steps. This axis changes ownership more than intelligence: an exported project is yours to change, and stops tracking anything we do afterwards.

Delivery decides how the finding reaches you, and it is the one people underrate. An agent whose findings arrive at the wrong moment, or three times a night for nothing, is functionally an agent that is not running — because you stopped reading it in week two.

Evaluation is how the deliverable gets scored, and it is quietly the axis the others are read against. "Did that change help?" has no answer unless something scores the result the same way each time. A deterministic check is exact and sees only what you thought to assert; a judge with a rubric covers the fuzzy half and will disagree with itself at the margins.

Why the framing earns its keep

Two reasons, and neither is that composition is a new idea. It is not.

The first is diagnostic. When an agent disappoints you, "the model isn't good enough" is the available explanation and usually the wrong one. An agent that repeats yesterday's finding has a retrieval problem. An agent that re-derives what it already knew has a planning problem. An agent that confidently asserts something it never read has a tools problem, and no model upgrade fixes it. Naming the parts turns one vague complaint into a short list of things to check.

The second is that the parts are separable. Change the memory provider and the agent keeps its goal, its tools and its stored notes. Change the model and nothing else moves. That is what makes an agent something you can tune rather than rewrite — and it is why the analogy people reach for is hyperparameters: settings outside the thing itself that change what it does.

The analogy has a limit worth naming. A training run is swept against a loss curve that exists whether or not you look at it. An agent is scored against an eval you wrote yourself, so the whole exercise is bounded by how good that eval is.

What you can and cannot do with this today

You can set every one of these per agent, and each choice resolves at run time rather than being baked in. Every axis fails open: an unknown or unconfigured choice falls back to the default with a logged warning instead of blocking the build or killing the run.

You can also sweep five of them. Each agent's Tuning page (under /u/agents) carries an experiment runner that varies the model, memory, planning, retrieval and state axes on one fixed objective — the agent's own declared eval, which is never swept, while guardrails only observes. Its limits are stated plainly: a naive full grid, several runs per cell, stopped cleanly at a hard budget wall with partial results kept. It compares compositions; it does not invent them. And because no real sweep has been run and published yet, we still have no numbers to show you about which axis matters most — the instrument exists; the findings posts are gated on actually running it.

If you want to see what this deployment actually carries on each axis, the axes catalog renders straight from the registries — including the options it does not have configured, which are marked rather than hidden. And if you would rather meet the axes by making one set of choices, build an agent: every decision above comes up, in plain language, in the order it has to be settled.

Make it yours →