Why it matters · Lesson 2 of 4 · 6 minutes

Close the feedback loop

An agent becomes useful when actions change the environment and their results return as evidence. Trace that cycle and learn what a harness must do between model turns.

A tool call is a proposal, not an action

The model returns a structured request such as “call read_file with path src/main.py.” That request is still data. The harness checks it, decides whether the tool is available, validates its arguments, executes the function, and packages the result. A well-designed harness never treats model output as permission by itself.

One complete tool round trip
  1. User asks
  2. Model calls tool
  3. Harness checks
  4. Tool observes
  5. Model continues

Walk through an example

Task: “Count the words in this sentence and report the number.” The model requests count_words(text=...). The harness validates the tool name and text argument, runs the deterministic function, then appends a tool result such as {"count": 8} to the conversation. On the next turn the model sees the count and can answer.

# Model output: a request, not yet executed
call = {"name": "count_words", "arguments": {"text": "Count these words"}}

# Harness executes a registered tool and creates an observation
observation = {"ok": True, "count": count_words(**call["arguments"])}
history.append({"role": "tool", "name": call["name"], "content": observation})

Provider APIs may require a call ID and a specific message shape for tool results. Preserve that correlation identifier in your adapter so each result answers the correct request. Keep provider-specific message formats at the edge of your harness; the internal loop can use one small, tested contract.

Errors are observations too

If a file is missing or a service is unavailable, the harness can return a structured error rather than pretending the operation succeeded. The model may recover—for example, by checking a different path—or the harness may stop and report the failure. Do not silently turn a failed tool call into an empty successful result; that teaches the model the wrong state of the world.

Useful result shape:
{"ok": false,
 "error": {"code": "NOT_FOUND", "message": "Requested file does not exist."}}

Return enough information to choose a next step, without leaking stack traces, credentials, or unrelated records.

Connect it to reliability

Without observations, the model cannot verify whether its action worked. With observations, a harness can support an iterative process: propose, act, inspect, and revise. This is the key idea behind ReAct’s interleaving of reasoning, actions, and environment observations. The engineering lesson is simple: make the environment’s response accurate, relevant, and visible to the next turn.

After a tool succeeds, what should the harness do?

Primary source: ReAct: Synergizing Reasoning and Acting in Language Models. Also see Anthropic’s discussion of agent tool loops.

Ask your teacher to trace a real tool call with you if the message handoffs still feel abstract.