Properties of a Good Multi-Turn Agent Harness
A multi-turn agent harness can be understood as the system that maintains a reliable interaction loop between an agent and the environment…
Properties of a Good Multi-Turn Agent Harness
A multi-turn agent harness can be understood as the system that maintains a reliable interaction loop between an agent and the environment it is operating.
At a high level, the loop is simple:
system state
↓
harness constructs observation
↓
agent chooses action
↓
system executes action
↓
state transition
↓
result + updated observation
↺
A good harness makes this loop useful across many turns.
Observation is shown here as something the harness constructs from state, rather than necessarily as a separate action the agent must request.
1. State
The harness must preserve the state that matters to the interaction.
Some of this state belongs to the application being operated: the current selection, focused control, open modal, editable buffer, running task, or other runtime condition.
Some of it belongs to the agent’s task: the user’s goal, constraints, decisions already made, unfinished work, and relevant history.
The harness may also need to preserve what has already been exposed to the agent: which entities, properties, transitions, and references the agent has seen. This disclosure state allows later observations to emphasize changes and newly relevant information without repeatedly transmitting the same context.
The important property is not retaining every previous token. It is retaining enough state to continue the interaction correctly.
2. Observation
The harness must expose the current state to the agent in a form that supports reasoning.
Raw text, screenshots, and logs can work, but they often force the model to reconstruct interaction structure that already exists inside the system. They can also fill the context with information that is not relevant to the agent’s current decision.
A better observation exposes that structure directly where possible.
Observation should not necessarily require the agent to perform a dedicated observe action. After any interaction, the harness may return the direct result of that interaction together with additional state that is useful for deciding what to do next.
The harness should therefore determine what information is useful to expose at a given point and disclose it progressively.
It should use what the agent already knows to avoid unnecessary repetition, while still introducing previously undisclosed information when that information becomes relevant. The agent should not have to perform a particular prior action before the harness is willing to expose useful state.
For example:
$ harness run "npm test"
task:
@task1
command: npm test
status: failed
exit_code: 1
error:
@error1
test: auth test
expected: 401
received: 500
relevant:
@file3 src/auth.ts
editable: true
available_actions:
@action1 inspect @file3
@action2 rerun @task1
@action3 inspect @error1
The agent asked to run the tests. It did not separately ask which file might be relevant, whether that file is editable, or what actions are now available. The harness exposed that information because it became useful after the transition.
This does not mean that every observation should contain every property of the environment. Depending on the current state and the agent’s task, useful observations may include several kinds of information.
2.1 What exists
The agent should be able to learn which entities exist when those entities become relevant to the interaction.
For example, a harness operating over a workspace might expose files as structured, addressable objects:
$ harness {some action}
{action result}
workspace:
@file1 README.md
@file2 src/server.ts
@file3 src/auth.ts
@file4 package.json
The important information is that these files exist and can be referred to later. The agent does not need a recursive filesystem dump unless that additional structure becomes useful.
The harness may initially expose only a small part of the workspace and reveal additional entities as the task develops.
2.2 What is selected
When selection affects the next decision, the observation should make it explicit rather than requiring the agent to infer it from previous output.
$ harness {some action}
{action result}
files:
@file1 README.md
@file2 src/server.ts
@file3 src/auth.ts [selected]
This lets the agent reason about commands such as “edit the selected file” without reconstructing selection from earlier turns.
Selection does not need to be repeated on every turn if the agent already knows it and it has not become relevant again.
2.3 What is modifiable
When the agent may act on an observed entity, the harness should expose whether that entity can be modified and, where useful, what kinds of modifications are supported.
$ harness {some action}
{action result}
@file3 src/auth.ts
editable: true
operations:
- replace
- append
- rename
@file4 package-lock.json
editable: false
reason: generated file
This prevents the agent from having to guess whether an action is legal or useful.
Such capabilities can also be disclosed only when they become relevant. A file listing, for example, does not necessarily need to include editability metadata for every file.
2.4 What is active
The harness should expose runtime state that affects what can happen next.
$ harness {some action}
{action result}
active:
@task1
command: npm test
status: running
elapsed: 4.2s
focus:
@file3 src/auth.ts
An agent receiving this observation knows that a task is still running and can decide whether to wait, cancel it, or continue with unrelated work.
Again, the harness should expose this state because it affects the current decision, not because every observation must contain a complete description of all active runtime state.
2.5 What changed or became relevant
On later turns, the harness should usually emphasize meaningful state transitions rather than repeatedly sending the entire environment.
$ harness {some action}
{action result}
changed:
@task1
status: running -> failed
exit_code: 1
@file3
modified: true
new:
@error1
source: @task1
message: "Expected status 401, received 500"
This is especially useful in multi-turn interactions. The agent already knows much of the previous state, so what it often needs most is the delta.
However, useful observation is not limited to things that changed.
Something may have existed in the environment for several turns without being relevant enough to expose. A transition can make that existing state newly useful.
For example:
$ harness run "npm test"
task:
@task1
status: failed
new:
@error1
test: auth test
expected: 401
received: 500
relevant:
@file3 src/auth.ts
editable: true
@file3 did not necessarily change. It became relevant because of the test failure.
Later observations should therefore emphasize both:
meaningful state changes
previously undisclosed state that has become relevant
This allows the harness to avoid repeatedly sending known information without requiring the agent to explicitly discover every useful piece of context.
2.6 What actions are currently possible
The observation should expose actions that are grounded in the current system state when those actions are useful to the agent’s next decision.
$ harness {some action}
{action result}
@action1 edit @file3
@action2 rerun @task1
@action3 inspect @error1
@action4 run "npm test"
These actions may be generated dynamically. For example, rerun @task1 only makes sense because @task1 exists and has reached a state where rerunning it is possible.
Automatically exposing useful actions does not remove the need for explicit discovery or inspection. The harness cannot always know which additional information the agent will want.
The two mechanisms can coexist:
automatic disclosure
→ the harness exposes context likely to help with the next decision
explicit inspection
→ the agent requests additional context when needed
Progressive disclosure reduces unnecessary discovery steps without requiring the harness to predict every future action.
2.7 Observation as a response to interaction
Taken together, these properties mean that an observation is not necessarily a complete snapshot and is not necessarily the result of an explicit observation command.
A harness response can instead be understood as a combination of:
direct result of the action
meaningful state transitions
newly relevant context
grounded next actions
For example, a poor harness might return an entire terminal transcript after a test command:
$ harness run "npm test"
Welcome to GenericOS 1.0
Last login: Mon Aug 10 09:01:22
user@machine:~/project$ ls
README.md src package.json package-lock.json
user@machine:~/project$ cd src
user@machine:~/project/src$ ls
auth.ts server.ts
user@machine:~/project/src$ npm test
> project@1.0.0 test
> node test.js
Running test 1…
Running test 2…
FAIL auth test
Expected status 401
Received status 500
user@machine:~/project/src$
The agent must reconstruct from this that the test finished, that it failed, which failure matters, which existing file may now be relevant, and what it can do next.
A better harness can expose the same interaction state directly:
$ harness run "npm test"
transition:
@task1
command: npm test
status: failed
exit_code: 1
errors:
@error1
test: auth test
expected: 401
received: 500
relevant:
@file3 src/auth.ts
editable: true
available_actions:
@action1 inspect @file3
@action2 rerun @task1
@action3 inspect @error1
The second representation does not necessarily contain less information about the interaction. It contains less information that the agent has to interpret before deciding what to do next.
The observation does not need to reproduce the application’s internal implementation or expose all available state. It needs to provide a grounded representation of the parts of state that are useful to the agent at the current point in the interaction, while allowing additional state to be disclosed as the interaction develops.
3. Addressing
The agent must be able to refer back to things it observed.
If an observation contains a buffer, list item, button, file, tool result, selected entity, or action, the harness should provide a stable way to address it.
This creates a connection between perception and action:
observe item7
↓
act on item7
References may be persistent or valid only for a particular snapshot. What matters is that their validity is explicit and tied to state.
Progressive disclosure should not change the identity of an entity. When the harness later exposes additional information about something the agent has already observed, it should retain the same reference whenever that reference remains valid.
4. Actions
The harness must expose the transitions the agent can cause.
Ideally, these actions are grounded in the system’s actual interaction machinery rather than invented independently by the agent.
An action might be:
type text
press a key
select an item
invoke an operation
call a tool
submit a prompt
cancel
wait for a transition
The vocabulary can vary between environments. The important point is that actions correspond to real transitions available from the current state.
Explicit inspection or discovery actions can still be useful. Progressive disclosure reduces the need for the agent to perform unnecessary discovery steps, but it does not require the harness to predict every piece of information the agent may want. The agent should still be able to request additional state when needed.
5. Transitions
Executing an action is not enough. The harness must determine what happened afterward and construct the observation that follows from the resulting state.
A transition therefore has a basic form:
state₀
action
↓
system execution
↓
state₁
↓
harness constructs
- direct action result
- meaningful state changes
- newly relevant context
- grounded next actions
The harness should be able to distinguish between an intended action, successful execution, and the transition that actually occurred. The observation returned afterward should reflect the resulting state rather than merely echoing the requested action.
Multi-Turn Interaction
Multi-turn behavior is largely the persistence of this loop over time.
Each turn begins from the state produced by previous turns rather than reconstructing the task from scratch.
The agent repeatedly receives an observation, acts against it, and receives another observation constructed from the resulting state. That observation may combine the direct result of the preceding action with meaningful state changes and additional context that has become relevant.

The observation does not need to be a complete new snapshot. It can preserve what the agent already knows, emphasize what changed, and introduce existing state when that state becomes relevant.
User input can enter this loop at any point and alter the task state or intended trajectory.
Most Harness Features Follow From This Model
Many properties commonly associated with agent harnesses are consequences of maintaining this loop correctly.
Memory is persistence of relevant state.
Context management is construction and progressive disclosure of the current observation.
Tool calling is one mechanism for executing transitions.
Tool results are one source of observations produced by those transitions.
References provide addressing between observations and actions.
Task tracking preserves what the agent has seen so the harness can emphasize meaningful state transitions while introducing additional existing state when it becomes relevant.
These are not separate principles so much as mechanisms for preserving the integrity of the same interaction loop.
The Core Principle
A good multi-turn agent harness therefore has a compact definition:
It preserves relevant state, progressively exposes the parts of that state useful to the agent in an addressable form, provides grounded actions over it, and faithfully carries the system through repeated action–transition–observation cycles.
Everything else exists to make that loop reliable.
메타데이터
- post_id
- 4d3a5b3bde45
- slug
- properties-of-a-good-multi-turn-agent-harness-4d3a5b3bde45
- url
- https://medium.com/@ohadrubin/properties-of-a-good-multi-turn-agent-harness-4d3a5b3bde45
- canonical_url
- https://medium.com/@ohadrubin/properties-of-a-good-multi-turn-agent-harness-4d3a5b3bde45
- author_url
- https://medium.com/@ohadrubin
- status
- ok
- fetched_at
- 2026-08-12 21:32:53