Harness Engineering, Two Frameworks: Illustrated Articles
An eight-part series on the six things an agent harness does that the model cannot, each one built twice: once in the Claude Agent SDK and once in LangChain Deep Agents. This edition carries the full
Agent = Model + Harness
The model is the easy part. The harness is where reliability lives.
You can buy the model. You own everything around it: memory, contracts, context, recovery, orchestration, human approvals, and observability. This series builds the same minimal agent in Claude Agent SDK and LangChain Deep Agents to show what actually makes an agent production-ready.
Introducing an eight-part series on the six things an agent harness does that the model cannot, each one built twice: once in the Claude Agent SDK and once in LangChain Deep Agents. Each edition carries full diagrams and code listings inline.
Subscribe today to see all eight parts. And join the conversation on harness engineering and loop engineering. I want you to share your thoughts and ideas.
What this is
You called a model, wrapped a loop around it, gave it a tool, and shipped it. Then it booked a flight for March 32nd, forgot what the user said two turns ago, retrieved a payment it had already made, and degraded so quietly that you heard about it from a customer rather than from the dashboard. None of those are model failures. They are harness failures, and the harness is the part you own.
The framing line that runs throughout the series is: Agent = Model + Harness. The model is the easy part: you buy it. The harness is the discipline layer around it, the code that decides what the model is allowed to do, what it remembers, what it sees on each call, how it recovers, how it coordinates, and when it must stop and ask a human. This series names each of those functions, shows the specific failure mode it is meant to control, and then builds the same minimal agent twice so you can watch the concept survive the framework change.
Every part holds the idea fixed and swaps the harness. The Claude Agent SDK uses query() / ClaudeAgentOptions and the claude_agent_sdk package; LangChain Deep Agents uses create_deep_agent() from the deepagents package. Snippets are focused Python, each listing 70 lines or fewer, and assume ANTHROPIC_API_KEY is set.
The running idea
One sentence carries all eight parts: the model is a stateless function, and everything that makes it feel like a reliable colleague lives in the harness around it. Part 1 builds the naked agent so you can see the gaps with nothing covering them. Each later part closes one gap, in the order you actually hit them in production: contracts, then memory, then context, then recovery, then orchestration, then the human seam, then the telemetry that tells you any of it is working.
Who is this for
Backend and AI developers who have already wired an agent loop by hand and felt it get brittle. If you have called an LLM API more than once and chained tool calls together, you have the prerequisites. You do not need prior experience with either framework: the point of building everything twice is that you can read the harness function independently of the SDK that implements it, and pick the one that fits your stack.
How to read it
The files below are numbered in reading order. Part 1 establishes the control group, and each subsequent part closes a gap exposed by the previous one. Each part is self-contained enough to use as a reference later, and either framework’s listing stands on its own if you only run one stack. Every article carries its diagrams inline.
01. The naked agent and why it breaks. The control group: a bare model-plus-loop with one tool, built in both frameworks. Run it, ask a follow-up, and watch it start from zero. The three open seams (no memory, no validation, no recovery) are the rest of the series.
02. Tool contracts and validators: Deciding what the model may do. A PreToolUse hook denies a dangerous call before it runs; a validator inside the tool raises on bad input so the model gets a correctable error instead of executing.
03. Memory and durable state: Remembering across calls. ClaudeSDKClient tracks the session for you; a Deep Agents checkpointer keyed by thread_id does the same. Plus the working, persistent, and semantic tiers, and the gate that vets what you write.
04. Context assembly: Shaping what the model sees per call. A tight system prompt and narrow tools explicitly curate context; summarization middleware automatically compresses older turns so the window stays clean and bounded.
05. Recovery: rollback, retry, replay. Recovering when a step goes wrong. Capture a session_id and fork it to a branch without losing the original; replay from a checkpoint by re-invoking the same thread instead of restarting.
06. Orchestration and subagents: Coordinating specialized agents. A coordinator delegates to a scoped reviewer via SDK AgentDefinitions or Deep Agents subagents, so no single window has to hold every job.
07. Human-in-the-loop and approvals: Pausing for a human before irreversible actions. An ask decision in a PreToolUse hook, or declarative interrupt_on plus a checkpointer, gates the send/delete/pay actions that must never fire unattended.
08. Observability and drift detection: Watching what the model produced. Per-call spans and per-run cost via SDK hooks and ResultMessage, full LangSmith traces from Deep Agents, and the drift signals that catch silent degradation before users do.
By Rick Hightower, Spillwave. Part of a multi-topic course on building with Claude: Claude Code, the Claude Agent SDK, Claude Managed Agents, the Claude API, and adjacent frameworks (CrewAI, LangChain Deep Agents).



