The six components of a coding agent

The six components of a coding agent
6components in the harness of a coding agent
3layers: model family, agent loop and runtime supports
4checks before any tool is run
0dependencies in the Mini Coding Agent: pure Python
The 6 components of a coding agent (and why Claude Code feels smarter than a chat)
I also cover it in this 13-minute video on my Articulator EN channel.

Model, reasoning and agent: the engine and the carlink

Raschka starts with an idea I share: much of the recent progress in LLM systems doesn't come from better models, but from how we use them. Tools, context management and memory matter as much as the model itself. To talk about it, it helps to separate three concepts we tend to mix up:

  • Language model: the core. It predicts the next token.
  • Reasoning model: still a language model, but trained or prompted to spend more compute when answering: it reasons step by step, checks itself, or searches among several candidate answers.
  • Agent: a layer on top, a control loop around the model. Given a goal, it decides what to look at next, which tools to call, how to update its state and when to stop.

His analogy is a car: the language model is the engine; the reasoning model, a more powerful engine, but more expensive to run; and the agent harness is the whole car, what lets you get the most out of that engine.

The language model's engine, the reasoning model's more powerful engine surrounded by coins, and the agent harness as a kart.
The model is the engine; the harness is the whole car.

Two more terms. An agent harness is the software scaffolding around the agent: it manages context, tools, prompts, state and control flow. A coding harness is a special case, built for software engineering. Claude Code and Codex are coding harnesses; OpenClaw, on the other hand, is a more general agent harness.

The coding harnesslink

A model can solve coding tasks on its own, but coding is only partly about generating text. It's also about navigating the repository, searching, finding functions, applying changes, running the tests, reading the errors and keeping track of what matters. Raschka puts it with a smile: it's hard mental work, which is why we hate being interrupted.

A coding harness has three layers:

Model family

Provides the engine: a base model or a reasoning one.

Agent loop

Solves the problem iteratively: observe, inspect, choose and act.

Runtime supports

The plumbing: repo context, tools, permissions, memory and cache.

The three layers of a coding harness: model family, agent loop (observe, analyze, decide and act) and runtime supports (repo, tools, permissions, memory and cache).
The three layers of a coding harness.

When we talk about the harness, we mean the layer that assembles the prompts, exposes the tools, tracks file state, applies edits, runs commands, manages permissions, caches what doesn't change and stores memory. Today, that layer shapes almost the entire user experience. A web chat, by contrast, is closer to "chatting with uploaded files".

Here Raschka takes a stance. He thinks the vanilla versions of the top models already perform very similarly, so the harness is often what makes the difference. And he speculates: if we dropped a leading open-weight model, such as GLM, into a similar harness, it could perform on par with GPT in Codex or Claude Opus in Claude Code. That said, harness-specific post-training usually helps: OpenAI has kept a general variant of its model and another one specialized for Codex.

To show the pieces, Raschka wrote his own minimal agent, in pure Python with no dependencies. Its code marks the six components below with comments.

The six component cards: live repo context, prompt shape and cache, tools with validation and permissions, context reduction, session memory and bounded subagents.
The six components of a coding agent.

1. Live repo contextlink

It may be the most obvious component, but it's one of the most important. When you say "fix the tests", the model should know whether it's inside a Git repository, on which branch, and which project documents might contain instructions. That request isn't self-contained:

  • If the agent sees an AGENTS.md or the project's README, it can learn which command runs the tests.
  • If it knows the repository root and layout, it looks in the right place instead of guessing.
  • The branch, the status and the latest commits tell it which changes are in progress.

So, before doing any work, the harness inspects the repository, pulls the Git context and the project documents, and condenses them into a workspace summary. That summary is combined with your request, so the agent doesn't start from scratch on every prompt.

Diagram: the harness inspects the repository, pulls the Git context and the documents, condenses them into a workspace summary and a stable prefix, and combines them with your request before it reaches the model.
Before working, the harness condenses the repository into a summary.

2. Prompt shape and cache reuselink

We already have the repository data. But rebuilding and reprocessing it on every request would be a waste. Coding sessions are repetitive: the agent's rules don't change, neither do the tool descriptions, and the project summary barely changes at all. What does change on every turn is your latest request, the recent conversation and the short-term memory.

That's why a smart harness splits the prompt in two:

  • A stable prefix, with the instructions, the tools and the workspace summary, which it reuses from the cache.
  • The session state, which it appends at the end of each turn.
The prompt in two parts: a stable prefix reused from the cache (instructions, tools and workspace summary) and the session state, appended at the end of each turn.
A stable prefix that gets reused, and a state that changes every turn.

The difference from component one: that one gathers the repository facts; this one packages them and caches them for repeated model calls. There's no point spending compute rebuilding from scratch what hasn't changed.

3. Tools, validation and permissionslink

This is where it stops feeling like a chat and starts feeling like an agent. A plain model suggests commands as text, and you run them and paste back the result. In a coding harness, the model runs the command itself and gets the output.

But the harness doesn't let it improvise any syntax. It gives it a closed list of named tools, with clear inputs and clear limits: list the directory, read, search, run a shell command, or write a file. And the model has to pass the arguments in a shape the harness can check. When the model asks for an action, the harness stops and asks four questions:

Is it a known tool?

Only the ones on the closed list.

Are the arguments valid?

In a shape the harness knows how to check.

Does the user need to approve it?

Writing a file, for example, asks for permission.

Is the path inside the workspace?

The agent doesn't leave the repository.

Only when it passes every check does anything run. Then the result is clipped and fed back into the loop.

The Mini Coding Agent terminal asks for approval of write_file; next to it, the list: less freedom, more reliable, easier to use, no arbitrary commands and stays inside the repo.
In the Mini Coding Agent, writing a file waits for your approval.

In the Mini Coding Agent it looks like this: you ask it to "implement binary search in Python", and before writing the file it asks whether you approve. The harness gives the model less freedom, but that makes it more reliable and easier to use: it doesn't run arbitrary commands and it doesn't leave the repository.

4. Minimizing context bloatlink

Context bloat is a problem for every language model. They accept longer and longer contexts, but those are still expensive and can add noise. And a coding agent suffers from it even more: it reads the same files several times and piles up tool outputs and very long logs. If it kept everything at full fidelity, it would run out of tokens fast.

A minimal harness uses at least two strategies:

  • Clipping: it shortens document snippets, long outputs, memory notes and history entries, so that no text eats up the prompt budget just because it's long.
  • Summarizing the history: it turns the whole session into a small summary that fits in the prompt. The trick is to keep recent events in more detail, because they matter more for the current step, and to compress older ones more.

On top of that, repeated reads of the same file are deduplicated, so the model doesn't see it over and over.

History blocks on a timeline: older ones small and compressed, recent ones large and detailed.
Recent events in detail; older ones, compressed.

For Raschka, this is one of the most boring and underrated parts of agent design. But his line is the one I keep: a lot of what looks like model quality is really context quality.

5. Session memorylink

The previous component answered how much of the past goes back to the model on the next turn. This one answers a different question: what does the agent keep as a permanent record? And it splits it into at least two layers, usually stored on disk as JSON files:

Full transcript

All your requests, the tool outputs and the model's responses. You can resume it even if you close the agent.

Working memory

A small, distilled state, with the current task, the important files and recent notes. It doesn't just grow: it gets edited and compacted.

On the left, the full transcript with requests, outputs and responses; on the right, the working memory with the task, files and notes, which gets edited and compacted.
The two layers of session memory.

Working memory sounds like the compact history from component four, but it serves a different purpose. The compact history is for rebuilding the prompt: it gives the model a compressed view of recent events. Working memory is for keeping track of the task across turns. And every new event is written to both layers.

6. Bounded subagentslink

Once an agent has tools and state, the next step is delegation. In the middle of a task, it may need a side answer: which file defines a symbol, what a config says, or why a test is failing. Better to split it off into a bounded subtask, which can run in parallel and speed up the work.

A subagent is only useful if it inherits enough context to do real work. But if we don't restrict it, we'll end up with several agents duplicating work, touching the same files or spawning more subagents. As Raschka puts it: the tricky problem isn't how to spawn a subagent, but how to bind one. For example, with read-only access and a limited recursion depth.

A subagent inside a bounding box, with a read-only lock and a limited recursion depth.
The subagent inherits context, but within tighter boundaries.

In Raschka's agent, the subagent still runs synchronously, but the idea is the same. Claude Code has had subagents for a while, and Codex added them later. Codex doesn't force them into read-only mode: they usually inherit the sandbox and approval setup of the main agent. There, the boundary lies in scoping the task, the context and the depth.

What about OpenClaw?link

The six components are tightly intertwined in the code, but looking at them one by one helps you understand how a coding harness works, and why it makes the model far more useful than a multi-turn chat. Raschka closes by comparing it with OpenClaw, which has a lot in common:

  • Instruction files in the workspace, such as AGENTS.md, SOUL.md and TOOLS.md.
  • Saved sessions with history compaction.
  • Subagents and helper sessions.

But it's a different kind of system: a local platform for general agents that can also code, designed for many long-lived agents spread across chats, channels and workspaces. A coding agent, by contrast, is optimized for one person working in a repository who asks it to inspect files, edit code and run local tools efficiently. In OpenClaw, coding is an important task, but just one among several.

The coding agent as a small circle next to OpenClaw, a large circle with many agents spread across chats, channels and workspaces.
A lot in common, but a different kind of system.
In one sentence

The model is the engine, but the harness turns it into an agent: repository context, cached prompts, tools with permissions, trimmed context, session memory and bounded subagents.

Which component do you miss most in your agent?

Sourceslink

Continue reading

Last posts -->

Have you seen these projects?

Gymnasia

Gymnasia Gymnasia
Expo
React Native
TypeScript
OpenAI
Anthropic

Fitness app with two agents that run entirely on the device, with no backend, so the user's data never leaves the phone. A BYOK conversational coach with local tools and a remote system prompt with offline fallback, plus a food estimator that pulls macronutrients out of a photo of the plate, with barcode scanning against OpenFoodFacts.

LangGraph Deep Researcher

LangGraph Deep Researcher LangGraph Deep Researcher
Python
LangGraph
FastAPI
React
TypeScript
Docker

Multi-agent research system built with LangGraph. A supervisor breaks your question down into topics and launches search sub-agents in parallel; each one compresses its findings before handing them to a writer agent that produces the final sourced markdown report. Live streaming over WebSockets, a configurable model per role and bring-your-own API keys that are never persisted server-side.

Tau

Tau Tau
Python
LangChain

Multi-agent tutoring system for secondary school students, with one agent per subject and course material written and validated by a team of teachers. It was used with real students at a private school in Spain and at a secondary school in Colombia.

View all projects -->
>_ Available for projects

Do you have an AI project?

Let's talk.

maximofn@gmail.com

Machine Learning and AI specialist. I develop solutions with generative AI, intelligent agents and custom models.

Do you want to watch any talk?

Last talks -->

Do you want to improve with these tips?

Last tips -->

Use this locally

Hugging Face spaces allow us to run models with very simple demos, but what if the demo breaks? Or if the user deletes it? That's why I've created docker containers with some interesting spaces, to be able to use them locally, whatever happens. In fact, if you click on any project view button, it may take you to a space that doesn't work.

Flow edit

Flow edit Flow edit

FLUX.1-RealismLora

FLUX.1-RealismLora FLUX.1-RealismLora
View all containers -->
>_ Available for projects

Do you have an AI project?

Let's talk.

maximofn@gmail.com

Machine Learning and AI specialist. I develop solutions with generative AI, intelligent agents and custom models.

Do you want to train your model with these datasets?

short-jokes-dataset

HuggingFace

Dataset with jokes in English

Use: Fine-tuning text generation models for humor

231K rows 2 columns 45 MB
View on HuggingFace →

opus100

HuggingFace

Dataset with translations from English to Spanish

Use: Training English-Spanish translation models

1M rows 2 columns 210 MB
View on HuggingFace →

netflix_titles

HuggingFace

Dataset with Netflix movies and series

Use: Netflix catalog analysis and recommendation systems

8.8K rows 12 columns 3.5 MB
View on HuggingFace →
View more datasets -->