Agent Engineering in Three Layers: Prompt, Context, and Harness

    A practical framework for building agents that hold up in production. The article divides agent engineering into three layers — Prompt (how intent is expressed), Context (what the model sees within a limited window), and Harness (the environment the model runs in) — and explains each layer's responsibilities, deliverables, and failure modes. It also covers separating a stable prompt core from a variable shell, dynamic tool injection, output contracts, instruction precedence, context budgeting, tiered memory, summarization, retrieval hygiene, loop termination, sandboxing and permissions, hooks, skill modularity, and offline evaluation. Finally, it describes three common imbalances caused by tuning only one layer, a suggested bottom-up diagnostic order, and a three-phase rollout with the cloud capabilities that support each phase.

    1. From “Can Chat” to “Can Do the Work”: The Dividing Line in Agent Engineering

    A pattern keeps repeating in the agent boom of the past two years: demos impress, production collapses. With the same model and the same set of tools, a demo runs flawlessly, yet the agent gets stuck in loops, hallucinates tool parameters, “forgets” mid-way through long tasks, and takes unauthorized actions once it is wired into real business workflows.

    The problem usually is not the model itself. It is how the model is placed. Turning a large language model from a chat endpoint into an executor that can work autonomously over long stretches in a real environment means solving three classes of problems — independent of each other, yet tightly coupled:

    • How to express intent: how instructions can be understood reliably by the model. This is the Prompt layer.
    • What the model should see: how information, memory, and tool results are organized within a limited window. This is the Context layer.
    • What environment the model runs in: how the loop terminates, what tools can touch, and how errors are detected and intervened upon. This is the Harness layer.

    Early engineering practice put 80% of the effort into “how to phrase things.” As task complexity rose, the bottleneck moved — first to “what to show the model,” then to “where it runs.”

    Recently, a wave of high-profile open-source personal agent frameworks gained traction. Their appeal is not a single breakthrough but a systematic integration of key capabilities accumulated over the past few years:

    • dynamic prompt assembly;
    • context compression;
    • tiered memory;
    • modular skills with progressive disclosure;
    • hooks;
    • guardrail design;
    • tool calling;
    • computer-use capabilities that extend the permission boundary to the personal device.

    When these components mature at the same time and mesh together, the system changes qualitatively: it evolves from a single-purpose, vertical tool into a personal assistant with long-horizon autonomy.

    To understand this integration-style innovation, you need to see what each of the three layers is responsible for, and how each one fails.

    2. The Three-Layer Model: Boundaries of Responsibility and How Failures Propagate

    Layer Core question Main artifacts Typical failures
    Prompt How to phrase it System prompts, output contracts, tool descriptions Conflicting instructions, format drift, wrong tool selection
    Context What the model sees Context budget, memory, retrieval results Key evidence pushed out of the window, noise drowning out the signal
    Harness What environment it runs in Main loop, sandbox, hooks, evaluation sets Infinite loops, unauthorized actions, errors that cannot be attributed

    The three layers form a chain of tightening constraints. The Prompt layer defines the semantic space. The Context layer decides what information to include and what to drop under window constraints. The Harness layer keeps the process safe under system-level constraints.

    Any defect in one layer gets amplified by the layers below it. Vague prompts leave the context strategy with nothing to act on; noisy context leads the model to take wrong actions in the Harness.

    3. The Prompt Layer: From Static Prompts to Runtime Assembly

    3.1 Separate a Stable Core from a Variable Shell

    A maintainable agent prompt should be split into two kinds of content:

    • Stable core: role definition, behavioral principles, security and compliance red lines, and the output format contract. This part should be versioned, covered by regression tests, and change as little as possible from request to request.
    • Variable shell: the current task description, the list of available tools, snippets of the user profile, environment state (working directory, time, permission level), and lessons from recent failures.

    Mixing the two in one big string is the main reason prompt quality degrades quickly: every edit risks breaking unrelated behavior, and you cannot run targeted A/B tests or regressions.

    3.2 Dynamic Assembly: Inject on Demand Instead of Stacking Everything

    Tool descriptions and domain knowledge should not be dumped into the prompt in full, unconditionally. A common approach is to trim them by relevance:

    • Tool recall by current intent: inject only the signatures, parameter constraints, and a few usage examples of the candidate tools.
    • Keep niche tools “discoverable”: let the model ask for them explicitly or obtain them through retrieval.
    1. [Stable core]
    2. ├─ Role and goals
    3. ├─ Behavioral rules / safety red lines
    4. └─ Output contract (structured fields + failure representation)
    5. [Variable shell]
    6. ├─ Task context (user request, constraints, acceptance criteria)
    7. ├─ Tool subset (recalled Top-K + parameter schema)
    8. ├─ Environment state (permission level, available resources, time)
    9. └─ Memory excerpts (long-term preferences + relevant recent experience)

    3.3 Output Contracts Beat Free-Text Output

    For any step whose output will be parsed downstream, explicit constraints are more reliable than parsing after the fact:

    • Require fixed fields, enumerated values, and a defined way to express missing values.
    • Provide types and range examples for tool-call parameters.
    • Define how the model expresses “I don’t know.” Allow it to return a clear failure signal instead of forcing it to fabricate a plausible-looking parameter.

    3.4 Conflicting Instructions and Precedence

    When the system prompt, tool descriptions, user input, and external web content all appear at once, conflicts are almost inevitable. In engineering terms, you need to declare precedence explicitly (for example: system instructions > tool constraints > user instructions > external data), and mark external content as data rather than instructions to reduce prompt-injection risk.

    4. The Context Layer: Deciding What Information to Keep Within a Limited Window

    4.1 The Context Budget

    Treating the window as a fixed budget to manage is the most overlooked practice with the highest payoff. Set an upper limit and an eviction order for each type of content:

    1. BUDGET = {
    2. "system_core": 0.10, # Stable core; cannot be trimmed
    3. "task": 0.15, # Current task and acceptance criteria
    4. "tools": 0.10, # Tool schemas, trimmed by recall
    5. "evidence": 0.40, # Retrieval results, file excerpts, tool returns
    6. "memory": 0.10, # Long-term memory and experience
    7. "dialogue": 0.10, # Conversation history (after compression)
    8. "reserve": 0.05, # Buffer for output and sudden needs
    9. }

    The point of a budget is to turn “filling up the window” into “making a choice.” When a limit is exceeded, the system should compress, summarize, or re-rank retrieval — rather than let the window overflow naturally and crowd out the content that matters most.

    4.2 Tiered Memory

    • Working memory: intermediate state and plans for the current task; decays across turns.
    • Episodic memory: records of task successes and failures, used to reuse experience and avoid repeating mistakes.
    • Semantic memory: user preferences, domain facts, and environment configuration; stable over the long term.

    The write policy matters just as much. Not every conversation is worth storing. Use “does this change future behavior?” as the filter, and deduplicate, merge conflicting entries, and tag content with how current it is.

    4.3 Compression and Summarization

    Rolling summaries are a common technique, but they need protection against two kinds of degradation:

    • summaries losing key constraints (amounts, deadlines, permission conditions);
    • summaries piling up until the information becomes stale.

    Ways to improve this:

    • Keep structured facts and identifiers in the original text; do not summarize them.
    • Denoise and truncate large tool returns before they enter the history.
    • For long tasks, introduce a “state file” that externalizes progress into addressable storage and reads it back when needed.

    4.4 Governing Retrieval Results

    Tool and retrieval returns are the main source of noise. Effective practices include:

    • re-rank results by relevance and then truncate;
    • strip boilerplate and script noise;
    • attach source identifiers for traceability;
    • for very large structures, show a summary first and let the model decide whether to expand it.

    Letting the model “expand on demand” rather than dumping everything at once is the core technique for controlling cost and improving the signal-to-noise ratio.

    5. The Harness Layer: Putting the Model in a Controlled Runtime Environment

    5.1 The Main Loop and Termination Conditions

    The backbone of autonomous execution is a loop with guardrails. Engineering-wise, you must define explicitly:

    • a cap on actions per step;
    • maximum total duration and total cost;
    • detection of repeated identical actions or repeated failures;
    • an escalation path (hand over to a human, or return a failure).
    1. def run(task, ctx, tools, max_steps=30):
    2. for step in range(max_steps):
    3. plan = model.invoke(build_prompt(task, ctx, tools))
    4. if plan.is_final:
    5. return plan.result
    6. if ctx.repeat_detector.is_stuck(plan):
    7. return escalate(task, reason="loop_detected")
    8. result = sandbox.execute(plan, policy=ctx.policy)
    9. ctx.record(plan, result)
    10. ctx.maybe_compress()

    Missing termination conditions are the direct cause of “it starts and never stops” and runaway bills. Fixing them is more worthwhile than any prompt optimization.

    5.2 Tool and Permission Sandboxing

    Tool permissions should follow least privilege and be tiered by environment:

    • File access: limited to the working directory.
    • Network egress: restricted to an allowlist.
    • Destructive operations (deletion, bulk modification, sending data externally): require explicit confirmation or a second check.
    • Credentials: injected through a key management service; they should never appear in prompts or logs.

    When capabilities extend to operating a GUI or local applications, the boundary must be stricter:

    • allow actions only within authorized windows;
    • force human confirmation for irreversible operations;
    • log everything end to end so sessions can be replayed.

    5.3 Hooks and Middleware

    A hook mechanism is how cross-cutting concerns are pulled out of the main logic. Typical hook points include:

    • Before an action executes: validation, redaction, parameter correction.
    • After an action executes: result normalization, metric instrumentation.
    • Error paths: retries, fallbacks, alerts.
    • Session lifecycle: archiving and cleanup.

    With a unified hook layer, observability, auditing, and policy changes no longer require changes to business code.

    5.4 Modular Skills and Progressive Disclosure

    Package capabilities as independent skill modules that follow a unified metadata format: name, applicable scenarios, input/output constraints, and dependencies.

    • At first: expose only a summary to the model.
    • Once selected: load the full instructions and scripts.

    This “index first, expand later” structure keeps context usage under control, and lets each capability be tested, replaced, and rolled out gradually on its own.

    5.5 Evaluation and Regression

    Agent behavior is probabilistic, so you need an offline evaluation set that covers:

    • normal paths;
    • boundary inputs;
    • prompt-injection attacks;
    • tool failures;
    • timeouts.

    Metrics worth tracking include task success rate, average steps and cost, tool-call accuracy, the rate of blocked unauthorized actions, and the human-takeover rate.

    Run the full regression after every change to the prompt or the context strategy. Otherwise, quality drift goes unnoticed.

    6. Imbalanced Coupling: Three Typical Failure Patterns

    • Tuning only the prompt: adding “be careful” and “don’t make mistakes” to the prompt again and again, when the real problem is the context budget or a missing termination condition. Gains drop to zero quickly.
    • Piling on context: handing the model every document and every tool. Cost rises linearly while accuracy falls, and the model suffers “lost in the middle” in long contexts.
    • Adding only guardrails: writing more and more interception rules while the main loop has no failure detection, so the system spins between “blocked → retry → blocked again.”

    Diagnose from the bottom up:

    1. Confirm the Harness has termination, retry, and audit capabilities.
    2. Check whether the Context layer’s information selection is reasonable.
    3. Only then optimize how the Prompt is phrased.

    7. Rollout Roadmap and Cloud Support

    • Phase 1 (Usability): a unified model-invocation abstraction layer, a main loop with hard limits, a tool allowlist, and basic logging and tracing.
    • Phase 2 (Stability): context budget management, tiered memory, tool-result denoising, and an offline evaluation set with a regression pipeline.
    • Phase 3 (Scale): a skill marketplace with gradual rollout, policy as code, cost attribution at the task level, and multi-agent orchestration.

    On the infrastructure side, general-purpose cloud capabilities can cover these needs:

    • Object storage: session archives and state files.
    • Message queues: decoupling asynchronous tasks.
    • Container platforms: hosting tool sandboxes with resource isolation.
    • Logging services and monitoring/alerting: full-chain tracing and exception notifications.
    • Key management services: unified credential injection.
    • Data warehouses: evaluation and cost analysis.

    8. Conclusion

    The Prompt, Context, and Harness layers are not three optional techniques. They form a system in which all three must hold at the same time:

    • the Prompt layer determines whether the semantics are correct;
    • the Context layer determines whether the information is sufficient without being redundant;
    • the Harness layer determines whether the process is safe and attributable.

    Real engineering maturity shows up when all three layers have explicit budgets, constraints, and measurements — not when reliability rests on one “smarter prompt.” Applying this framework to your own agent system has more long-term value than chasing the feature list of any particular framework.