An agent is a model in a loop with tools
Strip away the marketing and the entire field reduces to one sentence:
That's it. A chat model answers once. An agent acts, observes, and acts again. The loop is what changed between 2023-era "paste your stack trace into ChatGPT" and today's "fix the failing tests" typed into a terminal.
Three components, three families of jargon:
- the model: the LLM itself (GPT-5.x-codex, Claude, etc.). Jargon here: context window, tokens, reasoning effort.
- the loop + plumbing: the software that runs the model repeatedly and wires it to the real world. Jargon: harness, scaffold, orchestration.
- the tools: the actions the model can request. Jargon: tool calling, function calling, MCP.
Every remaining lesson is just zooming in on one box of fig. 1.
Harness: the software you're actually running
This is the most under-explained word in the field, and the most important one to get straight, because when you invoke an agent, the model is maybe 80% of the outcome and the harness is the other 20%, and the 20% is what differs between products. The same model in two different harnesses behaves like two different developers.
What the harness does on every single turn
- Assembles the prompt. System instructions ("you are a coding agent, here are your rules"), your
AGENTS.md, the conversation so far, recent tool results. - Advertises tools. It sends the model a machine-readable menu:
shell,apply_patch,read_file… with parameter schemas. The model can only do what's on the menu. - Executes tool calls. The model never touches your disk. It emits a structured request, "run
pytest -x", and the harness runs it (inside a sandbox) and returns stdout/stderr as text. - Manages the budget. Truncates giant outputs, compacts old history, decides what the model gets to see.
- Enforces policy. Approval modes, sandbox boundaries, network rules. The model proposes; the harness disposes.
# one turn of the loop, from the harness's point of view → send system prompt + AGENTS.md + history + tool menu ← recv tool_call: shell{ cmd: "pytest tests/ -x" } → run (in sandbox, per approval policy) → send tool_result: "FAILED tests/test_auth.py::test_expiry ..." ← recv tool_call: apply_patch{ file: "auth/tokens.py", ... } ... repeat until model replies with plain text instead of a tool call
You'll also hear scaffold / scaffolding: an older, looser synonym from the research world, and agent framework (LangChain, LangGraph, the OpenAI Agents SDK), libraries for building your own harness rather than using a packaged one.
"Agentic" is a spectrum, not a switch
"Agentic" measures how much of the loop runs without you in it. The industry climbed this ladder in about four years:
| Rung | What it is | Who holds the loop |
|---|---|---|
| autocomplete | Copilot-style ghost text; predicts your next lines | You, entirely |
| chat | Q&A about code; you paste results back manually | You are the harness |
| agentic (supervised) | Codex CLI / Claude Code in a terminal: it edits and runs, you approve and steer | Shared |
| agentic (delegated) | Background/cloud agents: hand off a task, get back a PR | The agent; you review the diff |
Note the third row: in chat-era workflows you were the harness: you ran the commands, copied the errors, pasted them back. Agentic tooling automated you out of the plumbing, not out of the judgment.
Related terms that live on this ladder: autonomy (how far it goes before checking in), human-in-the-loop (any checkpoint where you approve or redirect), headless (running the agent non-interactively, e.g. codex exec in a CI job, no human in the loop at all).
Tools, tool calling, and MCP
shell with cmd=pytest") instead of prose; the harness executes it and returns the result as a new message.Two things senior devs usually find clarifying:
- The model only ever emits text. A "tool call" is just specially-formatted output the harness recognizes and acts on. All the agency lives in that contract.
- Tool design is API design. An agent with a good
apply_patchtool outperforms one told to echo whole files. Bad tool ergonomics degrade a great model, and this is a large part of what harness authors compete on.
Before MCP, every harness had bespoke integrations. After MCP, tools are portable: the same MISP or Slack connector can serve Codex CLI today and a different harness next year. When you edit config.toml to add an [mcp_servers] entry, you are extending the tool menu from Lesson 01.
Context: the window, and the engineering of it
This is the constraint that shapes everything. The model has no memory, no filesystem, no state. The harness reconstructs its world every single turn. Which makes the central craft of the field:
You already do this. Every time you write an AGENTS.md (or CLAUDE.md in that harness), build commands, conventions, "never touch the migrations", you are doing context engineering: front-loading knowledge the agent would otherwise burn turns rediscovering. Terms in this family:
- compaction: when the transcript nears the limit, the harness summarizes older turns to reclaim space. Why long sessions get vague about early decisions.
- context rot: quality degradation as the window fills with stale or noisy content; the reason "start a fresh session" is legitimate advice, not superstition.
- RAG (retrieval-augmented generation): fetching relevant snippets (via search, embeddings, grep) into the window on demand instead of stuffing everything in. Agentic harnesses mostly do this with tools: the model greps and reads files itself, which is just RAG where the model drives the retrieval.
- system prompt: the harness-authored standing instructions that outrank everything else in the window.
Subagents and orchestration
The motive is Lesson 04's constraint. Exploring a large codebase might chew through 100k tokens of reading; if a subagent does the exploring, the parent's window receives a 500-token summary instead of the whole excursion. Subagents are context isolation, not (primarily) parallelism, though harnesses increasingly run them in parallel too.
Adjacent vocabulary: orchestrator / orchestration (the parent agent, or a workflow engine, coordinating multiple agents), multi-agent system (several specialized agents, planner, coder, reviewer, collaborating), handoff (one agent passing control to another). Useful skepticism: multi-agent designs add real coordination overhead, and a strong single agent with good tools often beats a committee of weak ones. The pattern earns its keep on wide, decomposable tasks.
Sandboxes, approvals, and permissions
An agent that can run arbitrary shell commands is an agent that can run rm -rf, exfiltrate your env vars, or obey a malicious instruction hidden in a README it read (that last one is called prompt injection: structurally it is untrusted input reaching an interpreter). So every serious harness layers guardrails around the EXECUTE box:
- sandboxing: OS-level confinement of what commands can touch: workspace-only writes, no network by default. Codex CLI uses Seatbelt on your Mac; Linux setups use Landlock/seccomp or containers.
- approval mode / permission policy: when the harness pauses to ask you. Codex's ladder runs from read-only, through "ask before writing outside the workspace or touching the network," to full-auto. This is the human-in-the-loop dial from Lesson 02.
- allowlist / denylist: standing rules ("pytest is always fine; git push never is") so approvals don't become clickthrough fatigue.
The clean way to hold it: the model proposes, the harness disposes. Capability lives in the model; authority lives in the harness config, which is why that config, not the model card, is the security boundary you should actually review.
Evals and benchmarks
Public benchmarks you'll see quoted: SWE-bench (Verified): real GitHub issues from real repos; the agent must produce a patch that passes the repo's own tests; the de-facto standard for agentic coding. Terminal-Bench: tasks done purely in a shell. Older ones like HumanEval (single-function generation) are effectively saturated and tell you little about agents.
Two caveats worth carrying: benchmark scores measure a model + harness + prompt combination, not the model alone; and public benchmarks leak into training data over time (contamination), so treat headline numbers as directional. The professional move, the same one you'd make for any vendor claim, is a small private eval: ten tasks from your own backlog, run against each candidate setup.
The glossary, one line each
| Term | One-liner |
|---|---|
| agent | LLM + loop + tools, pursuing a goal until done. |
| agentic | Adjective for workflows where the system, not you, runs the loop. |
| harness | The software around the model: prompt assembly, tool execution, context management, policy. Codex CLI is one. |
| scaffold | Research-world near-synonym for harness. |
| tool / function calling | Model emits structured JSON requesting an action; harness executes and returns the result. |
| MCP | Open standard for packaging tools as portable plug-in servers. |
| context window | The model's entire, fixed-size working memory per call. |
| context engineering | The craft of choosing what fills the window. |
| compaction | Harness summarizes old history to free window space. |
| RAG | Retrieving relevant content into the window on demand. |
| AGENTS.md | Repo-level standing instructions the harness auto-loads (CLAUDE.md in Claude Code). |
| system prompt | Harness-authored instructions that outrank everything else. |
| subagent | Child agent with a fresh window; returns a summary, protecting the parent's context. |
| orchestration | Coordinating multiple agents or agent steps into a workflow. |
| human-in-the-loop | Any designed checkpoint where a person approves or steers. |
| headless | Agent running non-interactively (CI, scripts), no human in the loop. |
| sandbox | OS-level confinement of what the agent's commands can touch. |
| approval mode | Policy for when the harness pauses to ask you. |
| prompt injection | Malicious instructions in content the agent reads; untrusted input reaching the loop. |
| eval | Repeatable task set + grader for measuring agent behavior. |
| SWE-bench | Benchmark: fix real GitHub issues so the repo's tests pass. |
Five questions, no grades on file
1. In one turn of the loop, who actually executes pytest?
The model only ever produces text. The harness recognizes the tool-call format, runs the command (per sandbox and approval policy), and feeds stdout back in.
2. Codex CLI and Claude Code are best described as…
Both wrap a model with a loop, tools, context management, and policy. The model is a component they call.
3. The main reason to spawn a subagent is…
A child loop burns its own context on exploration and hands back only a summary. Parallelism is a bonus, not the point.
4. Writing a good AGENTS.md is an act of…
You're pre-loading the window with knowledge the agent would otherwise spend turns rediscovering, pure information logistics.
5. "The model proposes, the harness disposes" means the real security boundary is…
Capability lives in the model; authority lives in harness policy. Review the config like you'd review any privileged service account.