Have you built an agent harness yet?

teleforce1 pts0 comments

Have You Built an Agent Harness Yet? | Alejandro M. P.

Series: Build an Agent Harness

Have You Built an Agent Harness Yet?

AI doesn't remember your project, Markdown does

Do We Even Need Multiple Tools?

Sandboxing an AI Harness on macOS

Teaching Skills to an AI Harness

Replacing Bash with Swift in an AI Harness

The Hidden Furnaces of AI Agentic Products

Recaps, Another Hidden AI Furnace

21 April 2026<br>32min read

Have You Built an Agent Harness Yet?

21 April 2026

Alejandro M. P.

For years I have repeated a thing that I still believe. Every programmer should write a promise library once. I think agent harnesses are the 2026 version of that exercise.<br>If you use AI coding tools every day, and especially if you have opinions about agent workflows, subagents, MCPs, commands, skills, and whatever new ritual the week invented, build a tiny one yourself. Once. Not to ship it. Not because you are going to beat the existing ones, although honestly, with so much vibed slop around it would not be that hard. The point is that after you build one, the whole space stops feeling mystical. You stop thinking in terms of what big corp marketing wants and start thinking in terms of simple reality.<br>There is a model. There is a loop. There are tools. There is context. That is the heart of it.<br>Of course the real products do much more. But it’s still built around a core that is much simpler than people think.<br>What is an Agent Harness<br>A harness is just the little program that sits between the model and the outside world. That is it. Yes, a normal program with normal code. I guess nowadays we call it “classic”.<br>The model, the AI, does not touch your filesystem. The model does not open files. The model does not run commands. It only autocompletes text.<br>It is the harness that decides what messages get sent to the model, what context gets included, how the replies are interpreted, what tools the model has to see the world, and what result gets sent back after something happens locally.<br>That also means the conversation is yours.<br>This is one of the big things I think people should internalize. The continuity of the chat, the remembered context, the tool results, all of that is managed by the harness. The model endpoint is not secretly keeping your whole little world alive for you, it doesn’t have all your project in memory. The harness keeps appending messages and resending what matters. Sometimes even removing old ones!<br>Now, to be fair, modern APIs offer more stateful variants and convenience helpers on the server side. That changes the ergonomics, one would argue that for the worse, but not the core mental model. Somebody still owns the conversation contract, and when you build your own harness that somebody is you.<br>So the smallest possible mental model is this:<br>You send a message.<br>The harness, the program you are running and interacting with, adds a bunch of context that the user doesn’t see, what’s often called the “system prompt”, and sends that to the LLM.<br>The model replies with text, by autocompleting from the last message it has received, which includes the entire history.<br>Your program decides what that text means.<br>If needed, your program does something in the world.<br>The result goes back as more text and context.<br>That is the whole trick. No magic. No AGI.<br>Let’s build a simple Harness<br>I can describe what a harness is, but to make sure we internalize it let’s build a simple one, from scratch.<br>To start, let’s keep the first step easy and simple. Let’s just make a CLI app that lets you send messages to the AI and shows you the LLM responses. Very simple, but useful to see how this works if you’ve never seen it before, and a necessary step before we get into the proper agentic features.<br>Let’s start with a simple CLI Swift package. Nothing fancy. No framework for agents. No giant abstraction tower. Just swift package init --type executable and the bits we actually need. As usual for command line tools in Swift, I used swift-argument-parser. That gives me a proper executable entrypoint with typed arguments.<br>At this stage the executable needs only a few things:<br>The base URL of the LLM chat-completions endpoint.<br>The model name.<br>An API key, loaded from the environment.<br>That is already enough to talk to an LLM.<br>For this post we will assume we have access to some LLM API, which in my project is represented by OpenAICompatibleClient. It’s not the interesting part of the project, but it is useful glue. It takes messages, performs the HTTP call to an OpenAI-compatible endpoint, and gives us back the assistant text. Don’t think it does anything special, it’s literally just an HTTP request-response.<br>The SwiftAgentHarness app is just a AsyncParsableCommand that reads the arguments, validates the endpoint, loads the API key from the environment, instantiates the client, creates an Agent, and calls run():<br>@main<br>struct SwiftAgentHarness: AsyncParsableCommand {<br>@Option(help: "LLM chat completions endpoint.")<br>var baseURL:...

harness model agent build simple built

Related Articles