Agent Architecture, Harness, and Loop
Agent Architecture, Harness, and Loop
TL;DR
- An agent is a model inside a controlled loop; the harness is the runtime that makes the loop observable, bounded, testable, and safe.
- Agent loop: Plan (interpret goal, constraints, available tools, success criteria) → Act (call tool, retrieve knowledge, produce answer) → Observe (feed results back with provenance) → Decide (continue, retry, escalate, stop, or ask human).
- Harness enforces max steps, max tokens, wall-clock timeout, retry limits, and cost budgets; owns tool execution, policy gates, context assembly, tracing, memory writes, and final validation.
- Every agent execution must be deterministically replayable from stored inputs, model version, prompt version, context segments, and tool observations; this is essential for debugging and evaluation.
- Autonomy scales with blast radius: read-only assistants can act independently; production-change agents require human approval for high-impact actions.
Core Concepts
The Agent Loop Structure
An agent loop executes the following cycle:
-
Plan: The model reads the goal (what is the user asking for?), the constraints (what is forbidden?), the available tools (what can be done?), and success criteria (how do we know we succeeded?). The model decides what to do next: call a tool, retrieve knowledge, ask for clarification, write an artifact, or produce a final answer.
-
Act: The model executes the decision within the harness. Calling a tool invokes the tool boundary (which validates arguments and checks authorization). Retrieving knowledge queries the vector store or knowledge base. Writing an artifact creates a persistent object. Producing an answer generates text.
-
Observe: The harness feeds results back into the context, preserving provenance (where did this information come from? which tool call? when?). The model incorporates the observation and continues reasoning.
-
Decide: The harness checks loop health: have we exceeded max steps? have we spent too much money? is the model stuck in a loop (repeating the same reasoning)? Should we continue, retry with backoff, escalate to a human, or stop? The decision is policy-driven, not left to the model to decide.
Harness as Safety and Observability Boundary
The harness is the runtime that wraps the model loop. It is responsible for:
- Enforcement: max steps (prevent infinite loops), max tokens (prevent token explosion), wall-clock timeout (prevent runaway jobs), retry limits (prevent thrashing on transient errors), cost budgets (prevent spending runaway).
- Tool execution: the harness calls tools, not the model; it validates arguments, checks authorization, logs calls, and handles failures.
- Policy gates: the harness enforces policy (human approval required, data access denied, budget exceeded) before continuing.
- Context assembly: the harness selects what context to include in the next model call (system instructions, user intent, retrieved knowledge, tool results).
- Tracing: the harness logs every step: the input, the model’s reasoning, the decision, the tool called, the result.
- Memory writes: the harness persists learnings and session state.
- Final validation: the harness validates the final answer before returning it to the user (does it contain sensitive data? does it violate policy?).
Deterministic Replay and Debugging
Every agent execution must be replayable from its inputs and stored artifacts. Replaying means: given the same user input, model version, prompt version, context segments, and tool observations (stored traces), the model produces the same reasoning and output. This enables debugging (why did the agent make that decision?) and evaluation (does a prompt change improve or regress quality?). Replay is not dependent on external state (current time, random numbers, external service responses); it is deterministic within the stored context.
Deterministic replay requires:
- Storing initial inputs (user message, goal, constraints)
- Versioning the model (model name, version, parameters)
- Versioning the prompt (system prompt version, developer prompt version, few-shot examples version)
- Versioning context segments (which knowledge base? which documents? when were they retrieved?)
- Storing tool observations (exact tool responses, not just summaries)
- Storing model outputs at each step (what did the model decide to do?)
With these artifacts, a trace is replayable: re-run the model with identical inputs and it should produce identical output.
Loop Termination and Escalation
A loop terminates when: the model decides it has answered the question, or the harness enforces a termination condition. The harness checks termination conditions at each step: exceeded max steps, exceeded cost budget, wall-clock timeout expired, model called the same tool with the same arguments twice in a row (possible infinite loop), or a policy gate requires human escalation. Escalation means: stop the loop, summarize the work done so far, ask a human to make the decision, and resume with the human’s input. Escalation preserves context and avoids losing work; it is not the same as failure.
Single-Agent vs. Multi-Agent Systems
A single-agent system has one model reasoning with a shared set of tools. It is simpler to debug and understand. A multi-agent system has multiple agents, each with different instructions, tools, or approval boundaries. Multi-agent systems help when: one role needs read-only access and another needs write access, one workflow is high-risk and needs human approval while another is low-risk and autonomous, or different teams own different tools and need service boundaries. The trade-off: multi-agent systems are more complex (more moving parts, more inter-agent coordination, more potential for miscommunication) but can enforce stronger separation of duties and risk isolation.
Reflection and Self-Correction
Reflection is a technique where an agent produces an answer, reviews its own work, identifies potential issues, and corrects or refines the answer. Reflection can improve quality but increases latency, cost (extra model calls), and the risk of circular reasoning (the agent refines its answer, then refines the refinement, then…). Reflection should be time-boxed (max 2 reflection cycles) and outcome-driven (stop if quality is not improving). Reflection is most valuable for reasoning-intensive tasks (math, logic, code review) and least valuable for retrieval-based tasks (fact lookup).
Autonomy Scaled to Risk
Autonomy (the ability to act without human approval) should scale with the blast radius of possible actions. A read-only assistant (search documents, summarize information) can act autonomously; there is no risk of irreversible state change. A data-analysis agent (query database, produce reports) can act autonomously; the worst case is a wrong report, which is reversible. A production-change agent (deploy code, scale infrastructure, delete data) should require human approval for high-impact actions. The principle: autonomy should enable productivity without enabling catastrophic failure.
Agent Loop Timing and Costs
| Phase | Time | Cost | Owner | Observable |
|---|---|---|---|---|
| Plan (model reasoning) | 100ms - 10s | Proportional to context + model tokens | Model | Logged with reasoning |
| Act (tool execution) | 1s - 60s | Tool-specific (API, database, compute) | Tool | Logged with latency, arguments, result |
| Observe (context update) | 1ms - 100ms | Minimal (context assembly) | Harness | Logged with new context size |
| Decide (policy check) | 1ms - 1s | Minimal (policy evaluation) | Harness | Logged with decision reason |
Total per loop: typically 1-30s depending on tools called. A typical agent session: 3-10 loops until goal is achieved.
Common Pitfalls
- Pitfall: Treating a model response as a system boundary. Why: the model can be manipulated via prompt injection, jailbreaks, or simple misunderstanding; it is not an access-control layer. Fix: enforce policies (who can access what?) at the tool boundary and harness level, not by hoping the model respects instructions.
- Pitfall: Shipping an agent without replayable traces and eval baselines. Why: without traces, it is impossible to debug failures or investigate unexpected behavior; without baselines, it is impossible to detect regression. Fix: log every step (input, reasoning, decision, tool call, result), version all components (model, prompt, context, tools), and maintain eval suite.
- Pitfall: Letting retrieved content act like trusted instructions. Why: retrieved documents can be stale, misleading, or contradict policy; the model might over-weight them. Fix: mark retrieved content as information (not instruction), include explicit system instruction stating that policy takes precedence, and audit retrieved content.
- Pitfall: Giving tools broad credentials because the prototype worked. Why: a prototype might work in a lab with a well-behaved model and no adversary; production requires narrow scopes and audit logs. Fix: give tools only the minimum credentials needed; require server-side validation of all arguments; log all tool calls; require human approval for high-impact actions.
- Pitfall: Optimizing prompt cleverness before defining product risk and measurable quality. Why: clever prompts often appear to work in demos but fail on edge cases or under adversarial input; you cannot optimize what you do not measure. Fix: define success metrics, build eval suites before optimizing, measure before and after each change.