DESIGN TRADE-OFFS · SIDE BY SIDE

A 30-line agent loop is not wrong—it answers a smaller question

A tiny loop is ideal for learning tool calls. A harness addresses failure, recovery, governance, replacement, and long-term maintenance. Complexity moves into contracted boundaries.

Teaching-sized loop
while (true) {
  const reply = await model(messages, tools)
  messages.push(reply)
  if (!reply.toolCalls) break
  for (const call of reply.toolCalls) {
    messages.push(await tools[call.name](call.args))
  }
}

Local causality is clear. Add persistence, approval, cancellation, recovery, and surfaces, and every responsibility crowds the loop.

DeepSeek Harness
profile / bundle / patch
        ↓ compose
Context + scoped effects
        ↓ drive
Inbox → Turn → Step
        ↓ publish
SessionEvent + agent/*
        ↓ project
Web · CLI · ACP · SDK

The value is not fewer lines, but ownership, lifecycle, and test boundaries for each kind of change.

ConcernMinimal agentDeepSeek Harness
State truthIn-memory messages arrayAppend-only SessionEvent + projection
Execution unitOne loop iterationInbox → Turn → 1..n steps → settlement
Tool resultPush text directlyGuard pipeline + paired debt + settlement
PermissionIf inside each toolPreset → approval → monotonic guard
Long contextDrop old messagesCompaction + surface + spill + pair balance
Replace implementationEdit call sitesService definition → provider → consumer
Background workBuild another queueSubagent / Job / Workflow / Schedule contracts
Product compositionCopy config or forkProfile + Bundle + Patch + scoped disposal
USE THE SMALLEST SYSTEM THAT ANSWERS YOUR QUESTION

When should you graduate to a harness?

When you need cross-process recovery, multiple clients, auditable approval, replaceable capabilities, or parallel maintenance, explicit boundaries matter more than local line count.

Start from first principles
Learn DeepSeek Harness

An independent learning project. Explanations derive from source; upstream remains authoritative.