Making sense of the agent harness
Laura Schaufelberger
September 19, 2026
10 min read
Whenever I hear the term "harness" in conversations about generative AI, I visualise the following:
Figure 1. Upon user invocation, the harness enriches context from information sources and manages model calls for semantic inference.
The user, the harness, and the model form my cognitive coat rack for this domain. What I place on each hook depends on the given product or tool. Imagine a basic weather chatbot: the user is a human sending messages to the bot, the model is a vendor-provided large language model (LLM), and the harness is a simple script that fetches current weather reports from the web and passes messages back and forth between the user and the model.
Agentic products or tools of varying sophistication and complexity beyond the simple chatbot all hinge on a harness of some shape.
The agent falls apart (in my mind)
LangChain's detailed breakdown of the agent harness informs much of my understanding of its building blocks. But unlike my user-centric coat rack, LangChain opens with an agent-centric framing:
Agent = model + harness
Conceptually I kind of like this. The model is a dormant brain and the harness is the scaffolding that bridges the model into something more usable:
The agent is RoboCop: its model is the brain and spinal cord, and the harness is the armour. Once awakened, the agent is a long-running actor interacting with its world.
On the practical level, I find the agentic-centric framing less useful. Building blocks in generative AI products like chatbots and coding assistants can involve "skills", "instructions", "personas", and "tools" and their usage can spawn "agents" or "subagents". If the harness is composed of such building blocks, is it simply a configuration-time construct belonging to and activated by some kind of agent, or is the harness itself a type of brain with the ability to control a swarm of agents?
For any given generative AI product, tool, or system, where does the harness start and end? How fixed or malleable are the structural elements of the harness? In general, what is the bare minimum to qualify as a harness?
I park the questions concerning agent activation as philosophical ones and use the remaining questions to explore the scope, flexibility, and mechanisms of control behind the agent harness.
Starting with the model, simplified
The harness ends where the model begins. Calling the model invokes a stateless function: tokens go in, tokens come out.
Input:
<start_of_turn>user
Do you understand Swiss German?<end_of_turn>
<start_of_turn>model
Output:
Yes, I understand Swiss German (Schweizerdeutsch)!<end_of_turn>model
This is a very simplified representation of the requests and responses of modern language models1, but tokens in → tokens out is a handy heuristic.
On its own, a model is a massive stateless token garbler with no session memory. The harness is responsible for not only preparing individual messages to send to the model but also providing enough context about the current session. For a chatbot session, the full conversation history is typically provided alongside the newest message. For a coding agent, additional context can take the form of a previously generated text file summarising the purpose and contents of a code repository.
The harness at its minimum
The bare minimum for something to qualify as a harness is a mechanism to accept user input on a loop and pass messages to a model.
A custom interactive terminal loop (a REPL) hooked up to a model accepting user prompts as inputs is a most basic harness. A bit of TypeScript to manage tool calls along with the Anthropic SDK that answers questions about a project directory (i.e. this custom llm harness) is also fairly minimal.
Modern, popular chatbots and coding assistants are quite a bit more sophisticated but they too accept user input on a loop and pass messages to a model:
- Claude.ai
- ChatGPT
- Gemini
- Claude Code
- OpenCode
- OpenClaw
Each of these is an agent harness and evolve from the simple chat loop.
The harness is an integration service
The harness sits between the between the user and the model: its logic determines what goes in as tokens, what to persist, how to enrich the context, and what to return or display to the user.
Figure 4. The harness orchestrates message transformation activities as messages flow through the system.
In broad strokes, the harness is responsible for:
- context management: deciding what to provide to the model for a given call
- state management: persisting chat messages, files, and other artefacts across the duration of a session or even between sessions
- enrichment2: fetching information from available and relevant sources, such as the web or an intranet, to enrich calls to the model
- orchestration: the sequencing of any number of context management, state management, and enrichment steps for a given session
These capabilities are engineered with harness primitives3 like the filesystem, bash and code execution, curl, and git. I consider these primitives to be the structural elements of the harness and the more sophisticated building blocks such as tools and Agent Skills to be their higher-order constructs. Tools are powered by bash and code execution. Agent Skills are fashioned from the filesystem and context injection logic.
The prescence and surface area of any given primitive or higher-order construct depends on the product build and its constraints. The basic weather chatbot may very well have curl for fetching information from the web but no use for git, which is generally used for tracking code changes. A coding harness would typically include both curl and git. A tightly constrained harness may have very limited filesystem access, such as a single project directory, while a harness without any deliberate filesystem and bash constraints may be able to perform destructive actions on an entire drive.
Malleability of primitives and higher-order constructs depends on lifecycle events: a user writes a new Agent Skill, or a self-evolving harness improves an existing one.
The variability in the prescence, surface area, and malleability of these structural elements can make it difficult to visualise the harness as a single, clearly bounded structure. I define the harness by its set of influences and its potential surface area: harnesses are composed of the logic, tools, inputs, and operating system (OS) that inform the orchestration of model calls.
Harnesses are composed of the logic, tools, inputs, and operating system (OS) that inform the orchestration of model calls.
The harness and vendor control
In principle, the harness is independent of the model. Swapping one model for a compatible one does not change the harness; its purpose stays the same regardless of model choice.
However, in practice, product vendors build part of the harness themselves. They handle routine activities like tokenisation and vector embedding steps, simplify context management, and manage the chat loop. As Birgitta Böckeler puts it, these vendors build the inner harness. User customisations driven by steering mechanisms such as "skills", "instructions", or even custom code sit in the outer harness.
Model providers optimise their inner harness for their own model families and create vendor lock-in: Claude.ai and Claude Code work only with Claude models. By contrast, more flexible harnesses like OpenCode allow for model switching across model families.
Looking at the divider between the inner and outer harness is helpful for understanding the level of vendor control and harness flexibility. In the case of this custom llm harness, the divider is the Anthropic SDK. To use this harness with a model outside of the Claude family, its code needs to be modified to work with a different SDK compatible with the target model family. For example, to use this custom harness with an open-weights Gemma model requires a code change to install and make the appropriate calls to the new SDK of choice, such as the OpenAI SDK or the Google Gen AI SDK.
Swapping one model for a compatible one does not change the harness; its purpose stays the same regardless of model choice.
Em dashes and user control
The user interface is the point at which the harness begins. I consider the user to be a human, an agent, a system, or a cron job and the interface may be a website, a CLI, a TUI, or an API. User control sits within features of the outer harness: "instructions" or "skills" provide the ability set guidelines that steer model behaviour.
The effectiveness and limits of user control asserted through "instructions" or "skills" can be difficult to pin down for a given use-case. A system guideline defined within the inner harness may take precedence over a user-defined one, a policy gate may block the user's influence altogether, or the model's token garbling process may simply result in non-adherence to the user-defined guideline despite its prescence in input tokens.
The Em Dash episode of the 99% Invisible podcast explores user frustration when guidelines intended to steer models away from em dashes (“—”) are largely disregarded.
Em dashes in model responses were minimal around the time of ChatGPT's release in November 2022. By mid-2024, however, em dashes became ubiquitous, excessive, and immensely disliked. Despite having once been an expressive writing device inspired by the likes of Emily Dickinson, it became an indicator of LLM-generated prose. ChatGPT users tried desperately to tone them down or avoid them entirely.
One possible explanation for the dramatic shift in em dash usage is an undisclosed system prompt, or a steer, within the vendor controlled inner harness: in July 2025, Sam Altman claimed to have added the dashes to ChatGPT “for lols” during a podcast with Theo Vonn.
Another possible explanation is that the shift resulted from training updates across frontier models through the process of destructive scanning. Around the time of the “for lols” claim, a lawsuit revealed that Anthropic trained its models on “quite literally all the books in the world.”
In November 2025 users were finally given control over ChatGPT's em dash usage. “If you tell ChatGPT not to use em dashes in your custom instructions, it finally does what it's supposed to do,” Altman announced.
Unlike in traditional software, user customisations are mere suggestions rather than genuine controls. Other influences on model behaviour include its training data and the inner harness, details of which are not always disclosed to the user.
The harness is a wrapper
Users do not interact with the model directly—they interact with a harness wrapped around the model. The harness plays a significant role in the freedom of model choice, the flow of information, and the influence over model behaviour.
There is no one shape to the harness as agentic products vary in purpose, sophistication, and complexity. The harness performs an array of activities such as session management, memory management4, model selection, enrichment, policy enforcement, and response filtering.
The model provides the semantic inference capability: it may be open-weights or vendor-supplied, a large model (LLM) or a small model (SLM), self-hosted or remote. There may even be a mixture of models available to the harness. Swapping one model for another does not inherently change the harness, but the ability to do so and the sophistication with which it is performed does inform harness complexity.
Rather than thinking of the agent as comprised of the harness and the model, I think of the user as a human, a system, an agent, a cron job, or even a team interacting with the harness wrapped around a model. The harness is a key component of generative AI instrumental in system behaviour, with its own hook on my cognitive coat rack.
References
Böckeler, Birgitta. “Harness engineering for coding agent users.” Martin Fowler, https://martinfowler.com/articles/harness-engineering.html
Trivedy, Vivek. “The Anatomy of an Agent Harness.” LangChain Blog, https://www.langchain.com/blog/the-anatomy-of-an-agent-harness.
Mars, Roman. “The Em Dash.” 99% Invisible, episode 658, 2024. Podcast transcript: https://99percentinvisible.org/episode/658-the-em-dash/transcript/.
Von, Theo. "Sam Altman.” This Past Weekend podcast, episode 599, 2025. https://www.youtube.com/watch?v=aYn8VKW6vXA.