Module 1, Agent Harness Foundations

One turn of the agent loop

Context is assembled, the model answers, a permission check runs, a tool executes and its result is appended. Where state survives, where feedback comes from, and what stops the loop.

About 12 minutes

An agent session can run for an hour and touch thirty files. Underneath, it repeats one short cycle. Once you can picture a single turn of it, most agent behavior stops being surprising, and every part of a harness finds its place on the drawing.

One iteration

1. Assemble context 2. Model answers 3. Permission check 4. Tool runs in the environment 5. Result appended next turn text answer, loop ends refused or approved
One turn. The model never runs anything. The harness does, after a permission check.
  1. The harness assembles the context. Instructions, the list of available tools, the conversation so far and the results of earlier actions are put together into one input.
  2. The model reads that input and answers. Its answer is either text for you or a request to use a tool.
  3. If it is a request, the harness checks that the action is permitted. Depending on the rules it runs it, refuses it, or asks you.
  4. The tool runs in the execution environment, a folder on your Mac, a shell, a simulator, or a container elsewhere.
  5. The result is added to the conversation, and the loop starts again.

The model never runs anything. It writes a request. The harness reads the file or starts the build. That is why the harness, and not the model, decides what an agent can and cannot do.

What a tool looks like to the model

A tool is described to the model with three things. A name, a description in plain language and a schema for its arguments. Field names differ between providers. The shape is the same everywhere.

{
  "name": "run_tests",
  "description": "Runs the Swift tests of one package and returns the failures. Use it after every change to Swift code.",
  "input_schema": {
    "type": "object",
    "properties": {
      "package_path": { "type": "string", "description": "Folder that contains Package.swift." }
    },
    "required": ["package_path"]
  }
}

This description travels with every request. It is part of the prompt. The model decides to call run_tests, or not to, from these few lines. The second sentence of the description, the one that says when to use the tool, is often the one that makes the difference.

When the model wants the tool, its answer contains a structured request in place of prose.

{ "name": "run_tests", "input": { "package_path": "Packages/ShoppingCart" } }

The harness runs the tests and sends back what they printed.

✘ Test cart5_subtotalMultipliesPriceByQuantity() recorded an issue
  Expectation failed: (cart.subtotal → 14.00 EUR) == 42.00 EUR
1 of 7 tests failed.

On the next turn the model sees this text in its context, next to everything that came before. It can reason about the failure, read the file again and propose an edit.

Results are context too

Whatever a tool returns takes room in the context, like a file you would have pasted.

On Apple platforms this has a practical consequence. A full xcodebuild log runs to thousands of lines, nearly all irrelevant to a failure. An agent that reads it whole spends a large part of its context on noise, and may lose the three lines that mattered. The output of a tool is something you design. A command that prints only the failures serves an agent better than one that prints everything. Module 5 builds such commands.

What survives a turn

Four places hold state, and they do not last equally long.

Place Lasts Example
The context window The current session, and less than that when the harness summarizes old turns The conversation, files read, tool output
Files on disk Until someone deletes them The code, tests, a specification, a progress note
Instruction and memory files Loaded at the start of every session Conventions, commands, rules
Version control The whole history Commits, branches, what changed and when

Anything that must outlive a session has to leave the context window. A decision goes into a file. Progress goes into commits. A long task is split into sessions that each start from files, not from the memory of the previous one. Module 3 builds on this.

Where feedback comes from

Feedback is how the loop learns that something is wrong. It has four sources that differ in speed and in what they see.

Source Speed What it catches
Compiler Seconds Types, missing members, concurrency errors
Tests Seconds to minutes Behavior, as far as tests describe it
Linters and static analysis Seconds Conventions and suspicious patterns
A person Minutes to hours Intent, design, everything the others miss

The first three can answer the agent inside the loop, with no one relaying a message. The fourth is you, and your time is the scarce one. A good harness sends the agent to the compiler and the tests first, so that what reaches you has already passed them.

What stops the loop

A loop needs an end. There are four common ones.

  • The model answers with text and no tool request. It considers the task done, or it has a question.
  • A limit set by the harness is reached, such as a number of turns or a budget.
  • You interrupt it.
  • An action is refused and the model has no alternative.

The first is the one to watch. “The model considers the task done” is a judgment made from what is in its context. If nothing there says what done means, it stops when the code looks plausible.

There is a distance between what an agent says about its work and what is true of it. Call it the verification gap, and measure yours. Over your next five tasks, each time the agent says it is done, check with tests it did not write, and count how often the claim was wrong. Anthropic also reports that some models begin wrapping up early when they believe they are near the limit of their context, and calls it context anxiety. Both point the same way. Keep sessions short, and let a command decide when the work is finished.

Sources

Unlock the course to save your place and track the lessons you finish.

Questions on this lesson

Questions and answers are open to learners who unlocked the course. Unlock the course to read them and ask your own.