RC
Artificial IntelligenceSoftware Architecture

Harness Engineering: Building Reliable Systems Around AI Agents

A practical guide to the context, tools, permissions, state, validation, security, evaluation, and governance that turn AI models into dependable engineering agents.

RightCode AI Editor

Harness Engineering: Building Reliable Systems Around AI Agents

A capable language model is only one component of a dependable AI system. The surrounding harness determines what the model can see, which actions it can perform, how failures are contained, and whether its work can be trusted.

Harness engineering is the discipline of designing that operational layer. It combines context management, tool contracts, permissions, workflow state, validation, observability, evaluation, and human governance into a system that makes probabilistic model behavior useful in production.

The central idea is simple: do not ask a model to be reliable through instructions alone. Build software that makes the reliable path easy, makes unsafe actions unavailable, and produces evidence that the requested outcome actually occurred.

The Model Is Not the Product

An AI agent receives a goal, gathers context, chooses tools, performs actions, observes results, and decides what to do next. Reliability depends on every transition in that loop.

A strong model inside a weak harness may:

  • Modify the wrong file because retrieval returned stale context
  • Repeat a payment or database write after a timeout
  • Expose a credential through a prompt, log, or tool result
  • Treat a successful command exit as proof that the user-visible behavior works
  • Continue calling tools after the task has become unrecoverable
  • Claim completion without checking the system of record

A well-designed harness constrains this uncertainty. The model still reasons and adapts, but software controls the boundaries within which that reasoning can affect the world.

This distinction matters when comparing a chatbot with an agent. A chatbot can produce an incorrect paragraph. An agent can produce an incorrect paragraph, submit it to an API, update a database, send a message, or deploy code. As the consequences grow, harness quality becomes at least as important as model quality.

What a Production Harness Owns

A production harness should provide:

  • Focused, current context relevant to the task
  • Explicit tool permissions and resource boundaries
  • Typed inputs and structured outputs
  • Durable workflow state across retries and restarts
  • Idempotent operations for consequential writes
  • Validation before and after actions
  • Time, cost, token, and iteration budgets
  • Audit trails for decisions and tool calls
  • Human approval for high-risk operations
  • Clear stop conditions and recovery paths

These controls should be enforced by code, infrastructure, and policy. Prompt instructions remain useful for guiding judgment, but they are not a security boundary. A sentence that says "never delete production data" is weaker than a toolset that contains no production delete operation.

A Reference Execution Loop

The most useful mental model is a controlled state machine rather than an open-ended conversation.

  1. Accept the task. Normalize the request, identify the actor, and assign a request ID.
  2. Classify risk. Determine whether the task is read-only, reversible, externally visible, destructive, or regulated.
  3. Build context. Retrieve the minimum evidence needed for the current decision.
  4. Plan the next action. Ask the model for a structured action, not an unrestricted narrative.
  5. Authorize the action. Check tool, resource, environment, and actor permissions in software.
  6. Execute once. Apply timeouts and idempotency at the tool boundary.
  7. Observe the result. Capture a bounded, typed response with stable error semantics.
  8. Validate the outcome. Check the system of record or run the narrowest behavior test.
  9. Continue, recover, escalate, or stop. Make the transition explicit and persist it.

The model participates in steps such as context selection and action choice. The harness owns authorization, execution semantics, persistence, and evidence.

A compact workflow state might look like this:

{
  "runId": "run_01J5Q9...",
  "taskType": "create_review_draft",
  "state": "validating",
  "risk": "externally_visible_reversible",
  "attempt": 2,
  "budget": {
    "toolCallsRemaining": 6,
    "deadline": "2026-08-18T12:30:00Z"
  },
  "lastAction": {
    "tool": "posts.createDraft",
    "idempotencyKey": "run_01J5Q9:draft:v1"
  }
}

Persisting this state means a worker can resume after a crash without asking the model to reconstruct reality from conversation history.

Context Engineering: Give the Model the Right Evidence

More context is not always better. Large, unfocused prompts increase latency and cost, make prompt injection harder to notice, and can bury the information that actually controls behavior.

Begin with the smallest concrete anchor: a failing test, file, symbol, API response, database record, or user-visible behavior. Retrieve nearby evidence only when it can distinguish between plausible next actions.

Useful context has four properties:

  • Relevant: It directly informs the current decision.
  • Current: It reflects the present repository, environment, or system state.
  • Attributable: The harness records where it came from and when it was retrieved.
  • Bounded: A human can inspect it, and the model is not forced to search through noise.

Separate durable facts from temporary observations. Repository conventions, API contracts, and approved architecture decisions can be cached. A failing command, open editor selection, or deployment status should be refreshed before it controls an action.

Treat Retrieved Content as Untrusted

Files, web pages, issue descriptions, emails, and database fields may contain instructions written by an attacker or copied from an unreliable source. Retrieval should never silently promote content into system-level authority.

Tag context by source and trust level:

SYSTEM_POLICY       highest authority
ORGANIZATION_POLICY approved operational rules
USER_REQUEST        requested outcome and constraints
REPOSITORY_CONTENT  untrusted data that may describe code
EXTERNAL_CONTENT    untrusted reference material
TOOL_RESULT         observed data, not new instructions

Secrets should stay outside model context whenever possible. A tool can read a credential from a secret manager and use it internally without returning the value to the model. Redaction after exposure is useful, but preventing exposure is better.

Compact Without Losing Control Information

Long-running agents eventually need context compaction. A good summary retains:

  • The user-approved goal
  • Decisions already made and why
  • Current workflow state
  • Files or resources changed
  • Validation already performed
  • Open risks and blockers
  • Stable identifiers needed to resume

It should discard raw tool chatter, duplicate observations, and credentials. Compaction is a state-management operation, not merely text shortening.

Tool Design: Narrow Capabilities Beat Shell Access

Tools are the harness's real application programming interface. Their design determines the actions available to the model and the evidence available afterward.

Prefer a narrow operation such as posts.createReviewDraft over unrestricted Firestore access. Prefer deploy.preview and deploy.promote over a generic cloud command runner. Narrow tools reduce prompt complexity, improve authorization, and make audit records meaningful.

Each tool should define:

  • Required and optional parameters
  • A strict schema with size and format limits
  • Authentication and authorization rules
  • Allowed resources and environments
  • Timeout and cancellation behavior
  • Retry and idempotency semantics
  • Stable success and error responses
  • Whether the operation is reversible
  • The evidence returned after execution

Here is a simplified typed contract:

type CreateDraftInput = {
  title: string
  markdown: string
  sourceId: string
  idempotencyKey: string
}

type CreateDraftResult =
  | {
      ok: true
      postId: string
      status: 'review'
      replayed: boolean
      requestId: string
    }
  | {
      ok: false
      code: 'VALIDATION_ERROR' | 'CONFLICT' | 'RATE_LIMITED' | 'INTERNAL_ERROR'
      retryable: boolean
      requestId: string
    }

The model should not need to parse an unbounded console transcript to learn whether an operation succeeded. Stable fields make transitions deterministic.

Separate Read, Propose, and Apply

Many risky workflows become safer when split into phases:

  1. A read tool gathers current state.
  2. A propose tool calculates a change without applying it.
  3. The harness validates policy and presents a diff.
  4. An approval gate authorizes the operation when required.
  5. An apply tool performs exactly the approved change.
  6. A verification tool reads the resulting state.

This structure works for infrastructure plans, database migrations, content publishing, access-policy changes, and code refactoring.

Permissions: Enforce Least Privilege at Runtime

Permissions should be scoped across several dimensions:

  • Actor: Which user, service account, or organization initiated the run?
  • Tool: Which operations may this workflow invoke?
  • Resource: Which repository, bucket, collection, tenant, or account is allowed?
  • Environment: Is the action permitted in local, staging, or production?
  • Data class: Can the workflow access public, internal, personal, or regulated data?
  • Time: Does the authorization expire?

Do not give every agent the same toolset. A documentation agent may need repository reads and pull-request creation but no deployment credentials. A support agent may read a customer's account status but should not query every tenant. A publishing agent may create drafts while only an editor can publish them.

Short-lived credentials are preferable to static keys. When static credentials are unavoidable, load them inside the tool process, restrict their scope, rotate them, and ensure neither requests nor logs reveal them.

Idempotency and Durable Recovery

AI workflows are especially vulnerable to duplicate execution. A model may retry because a tool timed out, a worker may restart after committing a write but before recording success, or a user may repeat a request after receiving no response.

Every consequential write should accept a stable idempotency key. The server should bind that key to a hash of the normalized request.

The expected behavior is:

  • First request: execute the operation and store the result.
  • Same key and same request: return the stored result without executing again.
  • Same key and different request: reject with a conflict.
  • Different key targeting an existing unique resource: return a domain conflict.

Idempotency belongs at the service performing the write. A client-side note saying "I already called this" cannot protect against process crashes or concurrent workers.

Recovery also requires classifying errors:

  • Retryable: transient network failure, rate limit, or unavailable dependency
  • Correctable: invalid input the model can revise within policy
  • Conflict: stale state or duplicate resource requiring a fresh read
  • Denied: authorization or approval failure that reasoning cannot bypass
  • Terminal: an invariant violation or exhausted budget

Use bounded retries with exponential backoff and jitter. Never retry validation failures or authorization denials blindly.

Validation Is Part of Execution

A successful tool invocation is not proof that the task succeeded. It only proves that the tool returned a success response.

Validation should test the intended outcome at the closest reliable boundary:

  • For code changes, run the narrowest relevant test, type check, or build.
  • For API writes, read the created resource and verify important fields.
  • For publishing, query the public index and render the canonical page.
  • For infrastructure, compare observed state with the approved plan.
  • For an email, verify the provider accepted one message with the expected recipient and template ID.

The execution loop is:

hypothesize -> act -> observe -> validate -> adjust or stop

Validation must be independent enough to detect false success. If a tool writes a post and returns the object it intended to write, that echoed object is weaker evidence than reading the stored document through the normal query path.

Define Completion Before Starting

Each workflow should have explicit acceptance criteria. "Fix the login" is too vague. A better completion contract is:

  • A valid user can sign in.
  • An invalid token is rejected.
  • The session persists across one page reload.
  • No credential appears in client logs.
  • The focused integration test passes.

The harness can then evaluate evidence against these criteria instead of relying on the model's confidence.

Guardrails and Budgeting

Open-ended loops are expensive and unpredictable. Give every run budgets such as:

  • Maximum tool calls
  • Maximum model turns
  • Token or monetary limit
  • Wall-clock deadline
  • Per-tool timeout
  • Maximum retries per error class
  • Maximum number of modified resources

Budgets should trigger a controlled stop with a useful status: completed, needs approval, blocked, budget exhausted, or failed. The final report should state what changed, what was verified, and what remains uncertain.

Circuit breakers should stop a workflow when repeated failures indicate that more attempts are unlikely to help. Three authentication denials, for example, should lead to escalation rather than repeated key variations.

Human Governance at the Right Boundaries

Automation level should match consequence, reversibility, and uncertainty.

Low-risk actions can often proceed automatically:

  • Searching documentation
  • Summarizing logs with sensitive fields removed
  • Running read-only checks
  • Creating a local patch

Medium-risk actions may proceed with strong validation and easy rollback:

  • Creating an unpublished content draft
  • Opening a pull request
  • Updating a staging environment

High-risk actions should require explicit approval close to execution:

  • Publishing externally
  • Deleting data
  • Changing production access controls
  • Rotating credentials
  • Applying an irreversible migration
  • Sending regulated or legally significant communications

Approval should bind to a specific proposed action. Approving "fix production" is not equivalent to approving a particular migration plan and resource set. If the proposal changes after approval, obtain approval again.

A useful review package includes:

  • The proposed change or diff
  • Why the agent selected it
  • Resources and users affected
  • Validation completed so far
  • Rollback or recovery plan
  • Remaining uncertainty
  • The exact action awaiting approval

Observability: Reconstruct What Happened

Agent observability needs more than raw prompts. A production trace should connect model decisions, tool calls, workflow state, and business outcomes.

Record:

  • Run, request, actor, tenant, and correlation identifiers
  • Model and prompt-template versions
  • Context sources and retrieval timestamps
  • Tool name, sanitized arguments, latency, and result code
  • Authorization and approval decisions
  • Retry count and idempotency replay status
  • Token usage and estimated cost
  • Validation checks and evidence references
  • Final workflow state

Use structured events rather than prose-only logs. Avoid storing raw secrets, complete personal records, or unnecessary prompt content. Redaction rules should be tested, not assumed.

Useful operational metrics include:

  • End-to-end task success rate
  • Validated success rate rather than self-reported success
  • Human intervention rate
  • Approval rejection rate
  • Tool error and retry rates
  • Duplicate-action prevention count
  • Median and tail latency
  • Cost per successful task
  • Security-policy denial count
  • Recovery rate after interrupted runs

Trace data should answer two questions: "Why did the system take this action?" and "What evidence shows the requested outcome occurred?"

Evaluation: Test Workflows, Not Just Answers

Model benchmarks do not predict the reliability of a specific agent in a specific harness. Evaluate the complete workflow with the real schemas, tools, permissions, and stop conditions.

Build a scenario suite that includes:

Scenario Expected harness behavior
Clear valid request Complete and validate the outcome
Ambiguous requirement Ask for the minimum blocking clarification
Missing dependency Report the blocker without fabricating success
Duplicate request Replay the original result without another write
Same idempotency key, changed body Reject with a conflict
Stale context Refresh state before applying a change
Malicious instructions in retrieved content Treat them as data and follow trusted policy
Unauthorized production action Deny and preserve an audit event
Partial failure after a write Resume and verify without duplicating the action
Exhausted budget Stop cleanly with resumable state

Measure deterministic properties where possible. Did the agent call a forbidden tool? Did it write outside the allowed resource? Did it validate through the system of record? Did a retry create a duplicate? These signals are more actionable than subjective ratings alone.

Use Layered Evaluation

A mature evaluation program includes:

  1. Schema tests for tool inputs, outputs, and error handling.
  2. Policy tests for authorization and approval boundaries.
  3. Simulation tests with fake tools and controlled failures.
  4. Integration tests against staging services.
  5. Replay tests using sanitized production traces.
  6. Adversarial tests for injection, data exfiltration, and boundary bypass.
  7. Canary evaluation on a small portion of real low-risk work.

Pin model and prompt versions during evaluation. When either changes, rerun the workflow suite and compare validated outcomes, not only text similarity.

Security Threats the Harness Must Address

Prompt Injection

External content may tell the model to ignore policy, reveal secrets, or call a tool. Preserve authority boundaries, label untrusted content, minimize available tools, and enforce policy outside the model.

Data Exfiltration

An agent with broad read access and outbound network tools can leak data even without displaying it in chat. Restrict egress destinations, scope data access, inspect tool arguments, and tokenize or redact sensitive fields before model use.

Confused Deputy Problems

The agent may possess authority that the requesting user does not. Every consequential tool should authorize the originating actor and target resource, not merely trust the agent service account.

Supply-Chain and Tool Risk

Tool implementations, browser content, plugins, and package dependencies can be compromised. Pin versions, verify provenance, isolate execution, scan dependencies, and keep high-risk tools in separate trust domains.

Secret Exposure

Do not place secrets in prompts, source files, command output, or error messages. Prefer secret references that tools resolve internally. Apply output filtering as defense in depth and rotate credentials when exposure occurs.

Common Failure Patterns

The Giant System Prompt

Teams often encode every rule in one enormous prompt. It becomes contradictory, difficult to test, and easy for later context to dilute. Move invariants into schemas, permissions, state machines, and tool implementations. Keep prompts focused on judgment that genuinely requires the model.

The Universal Tool

A generic shell, SQL console, or cloud SDK is flexible but creates a huge blast radius. Wrap common operations in narrow tools and reserve broad access for isolated, explicitly approved maintenance workflows.

Success by Assertion

The agent says "done" because a command returned zero or an API returned 200. Require outcome-specific validation and attach the evidence to the final state.

Stateless Retries

The system resends an operation after a timeout without knowing whether the first attempt committed. Persist workflow state and enforce server-side idempotency.

Human Review Everywhere

Requiring approval for every tool call creates fatigue and turns governance into a checkbox. Place approval at meaningful consequence boundaries and automate low-risk validation.

Autonomy Before Observability

Expanding permissions before traces, metrics, and evaluation exist makes failures hard to diagnose. Make a bounded workflow observable first, then increase autonomy based on measured results.

A Practical Adoption Path

Harness engineering does not require building a general-purpose agent platform on day one. Start with one valuable, bounded workflow.

Stage 1: Read-Only Assistant

  • Limit tools to retrieval and analysis.
  • Record context sources and request IDs.
  • Evaluate answer grounding and refusal behavior.
  • Establish data-access and retention policy.

Stage 2: Reversible Drafting

  • Allow creation of local patches, review drafts, or proposed plans.
  • Add strict tool schemas and unique resource constraints.
  • Validate generated artifacts automatically.
  • Require a human to apply externally visible changes.

Stage 3: Bounded Execution

  • Permit low- and medium-risk writes.
  • Add durable state, idempotency, budgets, and recovery.
  • Verify outcomes through independent read paths.
  • Run canaries and monitor validated success rate.

Stage 4: Risk-Tiered Autonomy

  • Automate proven workflows within explicit limits.
  • Keep approval for high-impact actions.
  • Continuously evaluate new model, prompt, and tool versions.
  • Review permissions and production traces regularly.

At each stage, expand autonomy only when the current stage has measurable reliability and a credible incident response path.

Implementation Checklist

Before putting an agentic workflow into production, confirm the following:

Goal and State

  • The task has explicit completion criteria.
  • Workflow states and transitions are defined.
  • State survives worker restarts.
  • Terminal, blocked, and approval-required states are distinct.

Context

  • Context sources are attributable and refreshed when needed.
  • Untrusted content is labeled and isolated from policy.
  • Secrets are not placed in model context.
  • Compaction retains decisions, identifiers, and open risks.

Tools and Permissions

  • Inputs and outputs use strict schemas.
  • Tools expose the narrowest practical capability.
  • Authorization checks actor, resource, and environment.
  • Consequential writes support idempotency.
  • Timeouts, cancellation, and stable error codes are defined.

Validation and Recovery

  • Success is checked at the system of record.
  • Retryable and terminal errors are distinguished.
  • Retries are bounded and use backoff.
  • Partial completion can be resumed safely.
  • Rollback or compensation exists where appropriate.

Governance and Security

  • Risk tiers determine approval requirements.
  • Approval binds to a specific proposed action.
  • Egress and sensitive-data access are restricted.
  • Prompt injection and exfiltration scenarios are tested.
  • Credential rotation and incident procedures are documented.

Operations

  • Structured traces connect decisions, actions, and validation.
  • Logs are redacted and retention is intentional.
  • Cost, latency, intervention, and success metrics are monitored.
  • A workflow-level regression suite gates releases.
  • Model, prompt, policy, and tool versions are recorded.

Conclusion

Harness engineering turns model capability into an operational system. Its job is not to eliminate uncertainty from a probabilistic model. Its job is to contain that uncertainty with explicit state, narrow tools, least privilege, durable recovery, independent validation, and evidence-driven governance.

The strongest agent is not the one allowed to do everything. It is the one that can complete a valuable task within clear boundaries, recover when reality is messy, prove what happened, and stop when it should.

Model access will continue to become cheaper and more widely available. The durable advantage lies in the engineering around the model: the context it receives, the actions it is permitted to take, the checks that catch failure, and the trust earned through repeatable outcomes.

Related reading