Tejas Agent Harness Engineering Framework
Transform an unreliable AI agent using any model — even a cheap or outdated one — into a dependable, production-grade system by wrapping it in a deterministic harness instead of endlessly tweaking prompts.
// TL;DR
The Tejas Agent Harness Engineering Framework is a method for making unreliable AI agents production-grade by wrapping the model in a deterministic 'harness' instead of endlessly tweaking prompts. The harness is everything around the model — a tool registry, guardrails, context management, deterministic handlers, and a verify step that inspects evidence rather than trusting the model's self-report. Use it whenever an agent hallucinates, lies about success, loops infinitely, or hits auth walls, and especially when a cheap or small model must behave reliably. A great harness lets a weak model outperform an unharnessed frontier model.
// When should you build an agent harness instead of editing the prompt?
Use this skill whenever an AI agent is producing unreliable, hallucinated, or incorrect outputs and your instinct is to 'prompt it harder'. Also apply when building any agentic workflow that must interact with external systems, handle secrets securely, or guarantee a specific outcome regardless of the underlying model's non-determinism.
// What do you need before building an agent harness?
- agent_taskrequired
The specific job the agent must complete, stated plainly (e.g. 'upvote the first post on Hacker News', 'extract invoice data from a PDF'). - current_failure_moderequired
How the agent is currently failing — lying about success, crashing, getting stuck in loops, hitting auth walls, etc. - target_modelrequired
The LLM being used. Can be a cheap/small model intentionally — the harness compensates for model weakness. - external_systems
Any browsers, APIs, file systems, databases, or authenticated services the agent must touch. - secrets_or_credentials
Any login credentials, API keys, or tokens the agent needs access to — to be handled deterministically by the harness, never by the model.
// What are the core principles of harness engineering?
Harness = Everything Around the Model
The agent harness is NOT the model and NOT just the agent loop. It is everything around the model that gives it grounding in reality — the tool registry, guardrails, context management, verify step, and the agent loop wrapper. The model is the black box renter; the harness is the stable anchor you control.
Don't Prompt It Harder
When an agent fails, the instinct to change the system prompt or 'prompt it harder' is almost always wrong. The harness — guardrails, verify steps, deterministic handlers — is what changes the outcome. The prompt in Tejas's demo was never touched; the harness alone made the agent succeed.
Reliability Over Model Quality
The name of the game with a harness is reliability. A cheap, old, or small model wrapped in a great harness outperforms an expensive frontier model running unharnessed. Use the harness to do more with less.
Fail Correctly Before You Succeed
Step one to solving a problem is admitting you have one. The harness must force the agent to report failure truthfully before you can fix anything. Remove the lie first via a verify step, then address the root cause.
Deterministic Beats Probabilistic for Critical Steps
Any step that must be correct — authentication, secret injection, form submission, result verification — should be handled deterministically by the harness in code, not delegated to the non-deterministic model. The harness has access to secrets; the model should not.
// How do you build an agent harness step by step?
- 1
Define the agent task and identify the failure mode
State the task in one clear sentence. Then observe the agent running without any harness and document exactly how it fails: does it lie about success, crash on auth walls, loop infinitely, hallucinate tool calls? This is your target list for the harness to fix. Do NOT change the prompt at this stage.
- 2
Build a bare-bones agent loop with a tool registry
Create a minimal agent loop (while true → get response → if STOP return, else push to trace). Attach a tool registry: tools have a name, description, parameters, and an execute function. Use an existing SDK (e.g. OpenAI tool-calling SDK) rather than inventing the interface. Log everything to a trace — you will need this history for the verify step.
- 3
Add default guardrails to the loop
Implement at minimum two guardrails: (1) max_iterations — if the agent takes more than N tool calls/steps, kill the run; (2) max_messages — if the context grows beyond a threshold, compress it. Context compression can be naive at first: always keep system prompt + user prompt + last two messages, discard the middle. These guardrails prevent runaway spend and context overflow without any prompt changes.
- 4
Extract the loop into a named harness abstraction
Move all agent logic into a function called run_harness_attempt. Wrap that in a run_harness function that is simply a retry loop with a max_attempts guardrail (e.g. give up after 3 tries). The entry point should shrink to ~20 lines: define the prompt, call run_harness. This encapsulation is what makes the harness reusable and composable.
- 5
Write a deterministic verify step
Implement a verify function that inspects the trace (the history of tool calls and events collected during the loop) and deterministically decides pass or fail. Do NOT ask the model if it succeeded — check the evidence. Example logic: 'Was there a click on the upvote element AND is the current page state consistent with success AND were there no failed-login events in the trace?' Return early with failure for each known failure pattern (failed login, unexpected redirect, etc.). This removes the lie.
- 6
Add deterministic handlers for known obstacle patterns
For each category of obstacle identified in step 1, write a deterministic handler that fires inside the agent loop BEFORE the trace is updated. Example: a login_handler checks the browser's current URL on every iteration; if it detects a login page, it injects credentials from environment variables and submits the form programmatically — no model involvement. The handler then injects a message into the agent's queue: 'Harness: I logged in. You are clear to proceed.' Secrets never touch the model context.
- 7
Run, inspect the trace, and iterate on the harness (not the prompt)
Execute the harnessed agent. When it fails, read the trace to find where it went wrong and add a new guardrail, handler, or verify case. Repeat. The prompt remains constant throughout. Judge success only via the verify step's deterministic output, not the model's self-report.
// What does harness engineering look like in real scenarios?
A browser-use agent tasked with submitting a form on an authenticated internal tool keeps claiming success but the form was never submitted because it hit a login redirect.
Build a harness with: (1) a login_handler that fires every loop iteration, checks the URL, and if on the login page injects credentials from env vars and submits deterministically; (2) a verify step that checks the trace for a confirmed form-submission tool call AND absence of login-redirect events; (3) max_iterations guardrail of ~6 steps. Do not change the system prompt. The cheap model (e.g. GPT-3.5-level) can now complete the task reliably.
An enterprise RAG agent querying sensitive internal documents (invoices, call transcripts) needs to enforce data-access security and prevent the model from leaking credentials.
The harness owns all secrets and auth tokens — they are injected deterministically into retrieval tool calls, never placed in the model's context window. Guardrails enforce max context size with a compressor. A verify step confirms that retrieved chunks match the authorised user's data scope before the answer is returned. The model remains a black box renter; the harness provides enterprise-level security as a stable anchor.
// What mistakes should you avoid when building a harness?
- Prompting it harder: changing the system prompt when the agent fails is almost never the right fix — build or extend the harness instead.
- Treating the agent loop as the harness: the agent loop is just one component inside the harness. The harness is everything AROUND the model, including the loop wrapper, guardrails, verify step, and handlers.
- Letting the model self-report success: non-deterministic models will lie. Always use a deterministic verify step that inspects the trace, not the model's final message.
- Putting secrets in the prompt or model context: credentials and tokens belong in the harness (environment variables, secure stores), injected deterministically. Handing them to the model is a security risk and unnecessary.
- Skipping context management guardrails: without a max_messages guardrail and a context compressor, long agent runs will blow the context window and degrade performance — this is the harness's job to prevent.
- Building the harness for one specific model: the harness should be model-agnostic. The whole point is that a cheap or swappable black-box model can be made reliable by the surrounding harness.
- Waiting for a perfect context compressor: start naive (keep system prompt + user prompt + last two messages, discard middle). Ship the harness, then improve the compressor incrementally.
// What are the key terms in harness engineering?
- Agent Harness
- Everything around the model that gives it grounding in reality — the stable, deterministic environment that anchors a non-deterministic AI agent so it cannot drift off the rails. Analogous to a climbing harness anchored to a mountain: the model can move, but only within controlled bounds.
- Tool Registry
- The set of available tools given to the agent, each with a name, description, parameters, and an execute function. The harness owns and constructs the tool registry; the model only calls into it.
- Guardrails
- Hard limits enforced by the harness to prevent runaway agent behaviour. The two core guardrails are max_iterations (kill the run after N tool calls) and max_messages (compress context if message count exceeds threshold).
- Context Compressor
- A harness-managed utility that trims the agent's message history when the max_messages guardrail is triggered. Naive version: always preserve system prompt + user prompt + last two messages, discard everything in between.
- Agent Loop
- The inner while-true loop that sends a prompt to the model, receives a response, checks for a STOP signal, and otherwise pushes events into a trace. The agent loop is a component of the harness, not the harness itself.
- run_harness_attempt
- The function encapsulating a single attempt of the agent loop with all its tooling. Called by run_harness inside a retry loop bounded by max_attempts.
- run_harness
- The outermost harness function — a retry loop that calls run_harness_attempt up to max_attempts times, applying the verify step after each attempt to determine whether to retry or return.
- Verify Step
- A deterministic function (written in code, not delegated to the model) that inspects the agent's trace after each attempt and returns a definitive pass or fail. Removes the model's ability to lie about its own success.
- Trace
- The accumulated history of all tool calls, messages, and events produced during an agent loop run. The verify step and deterministic handlers read the trace to make decisions without querying the model.
- Deterministic Handler
- A harness-owned function that intercepts the agent loop at a specific condition (e.g. login page detected) and performs a critical action in code — injecting credentials, submitting a form, redirecting — without involving the non-deterministic model.
- Token Billionaires
- Tejas's term for engineers at companies (Anthropic, Google, etc.) who have essentially unlimited model access. The harness methodology is explicitly designed for everyone else — those who pay rent for compute and must do more with less.
- Dynamic On-the-Fly Harness
- Tejas's predicted next evolution: an agent that, before executing a task, autonomously generates its own harness — identifying where it might hallucinate or fail and creating appropriate guardrails and verify steps — then executes the harnessed plan and returns a guaranteed result.
// FREQUENTLY ASKED QUESTIONS
What is an agent harness in AI engineering?
An agent harness is everything around the model that grounds it in reality — the tool registry, guardrails, context management, deterministic handlers, and a verify step wrapped around the agent loop. The model is a non-deterministic black box you rent; the harness is the stable, deterministic anchor you control. It lets a cheap model behave reliably in production.
What is the Tejas Agent Harness Engineering Framework?
It's a method for transforming an unreliable AI agent into a dependable, production-grade system by building a deterministic harness around the model rather than rewriting prompts. The framework defines a bare agent loop, default guardrails, deterministic obstacle handlers, and a verify step that checks evidence in a trace. Its core promise: reliability comes from the harness, not from a bigger or better model.
How do I stop my AI agent from lying about success?
Add a deterministic verify step that inspects the agent's trace instead of trusting its final message. Write code that checks for concrete evidence — a confirmed click on the right element, the absence of failed-login events, a page state consistent with completion. Never ask the model whether it succeeded, because non-deterministic models will lie. The verify step removes the lie before you fix the root cause.
How do I make a cheap LLM reliable in production?
Wrap it in a strong harness. Build a minimal agent loop with a tool registry, add max_iterations and max_messages guardrails, write deterministic handlers for known obstacles like auth walls, and add a verify step that checks the trace. A cheap or outdated model inside a great harness outperforms an expensive frontier model running unharnessed — reliability comes from the surrounding system.
How does the harness approach compare to prompt engineering?
Prompt engineering tweaks the model's instructions and hopes a non-deterministic system behaves; harness engineering changes the deterministic environment around the model so critical steps can't fail. In Tejas's demo the prompt was never touched — the harness alone made the agent succeed. For anything that must be correct, like auth or verification, deterministic code beats a probabilistic prompt every time.
When should I build a harness instead of tweaking the prompt?
Build a harness whenever an agent produces unreliable, hallucinated, or incorrect outputs and your instinct is to 'prompt it harder.' Also use it for any agentic workflow that touches external systems, handles secrets, or must guarantee a specific outcome regardless of model non-determinism. If correctness matters, the harness — not the prompt — is what changes the outcome.
Why should secrets never go into the model's context?
Because the model is a non-deterministic black box and a security risk — it can leak or misuse credentials, and it's unnecessary. The harness owns all secrets in environment variables or secure stores and injects them deterministically into tool calls, like a login handler that submits credentials in code when it detects a login page. The model stays unaware the secret ever existed.
What results can I expect from harness engineering?
You can expect an agent that fails honestly, stops looping or hallucinating, handles auth walls automatically, and either completes the task or reports failure truthfully via the verify step. Expensive frontier models become optional — a cheap model becomes production-grade. You'll iterate on code (guardrails, handlers, verify cases) instead of chasing prompt wording, making reliability repeatable and composable.
What are guardrails in an agent harness?
Guardrails are hard limits the harness enforces to prevent runaway behaviour. The two core ones are max_iterations, which kills a run after N tool calls to prevent infinite loops and runaway spend, and max_messages, which triggers a context compressor when the message history grows too large. They protect against overflow and cost without touching the prompt.
What is a deterministic handler and when do I need one?
A deterministic handler is a harness-owned function that intercepts the agent loop at a specific condition — like detecting a login page — and performs a critical action in code without involving the model. For example, it injects credentials and submits the form, then tells the agent 'Harness: I logged in, proceed.' Use one for any step that must be correct: auth, secret injection, form submission.