DEV Community

Vikram Ray
Vikram Ray

Posted on

17 things your agent harness should have!

Do this first: go down the list and tick what your harness already does. Each unticked item is a failure your agent will hit.

The list comes from reading the source of OpenHands SDK, OpenCode, Hermes Agent, DeepSeek harness and Strands harness. Items 1–6 are the basics everyone builds. Items 7–17 are what separates these harnesses from a model in a loop. The rule behind all of them: the prompt is for judgement; anything a script can check is enforced in code.

The list

  1. A tool loop. Model call, tool calls, results back, repeat until the model answers. Everything else hangs off it.
  2. Summarization. Old turns get summarized so long runs keep going. OpenHands keeps the first messages untouched and makes the summary track open tasks (condenser); Strands never drops pinned messages (summarizing manager).
  3. Subagents. Hand a focused task to a fresh agent with its own tools, and get back one answer (Strands subagent.py).
  4. Skills. Instructions loaded only when the task needs them. OpenHands loads them on keywords and on file paths the agent touches (trigger.py).
  5. Model retries. Back off and retry on provider errors. Strands defaults to 6 attempts (_retry.py).
  6. Hooks. Run your own check before or after any tool call, on each prompt, and on stop. OpenHands follows Claude Code's convention: a hook that exits with code 2 blocks the call (hooks/manager.py).
  7. Errors that name the next step. A refusal says why and what to do instead. OpenCode answers a missing file with "Did you mean one of these?" (read.ts); DeepSeek's sandbox says "retry this exact command once with sandbox_permissions + justification" (escalation.ts).
  8. Read before edit. Refuse an edit to a file the agent never read, or one that changed since: edit requires reading "X" first (DeepSeek). Hermes warns "was modified since you last read it" (read tracking).
  9. Repeated-call detection. Same tool, same arguments, again. DeepSeek reminds at 3, 5 and 8 repeats (repeat-tool-reminder); Hermes warns, then blocks, then halts (tool_guardrails.py); OpenHands nudges once, then stops the run (stuck_detector.py).
  10. A step budget that takes tools away. When it's spent, OpenCode sets toolChoice: "none", appends a wrap-up message, and refuses any call that still arrives (max-steps.ts, llm.ts). The run ends with an answer, not a crash.
  11. "Done" is checked, not trusted. Hermes sends the model back to run its tests after a code edit (verification_stop.py). OpenCode's judge is told "The assistant claiming the goal is met is not evidence" (judge.txt).
  12. Remove tools instead of forbidding them. OpenHands' planning agent can only edit PLAN.md (planning.py); OpenCode's explore agent starts from deny-all (agent.ts); Hermes subagents never get delegate or memory tools (delegate_tool_toolsets.py).
  13. Parse shell commands before running them. OpenCode checks each command and target folder as a permission (shell.ts). Hermes keeps a blocklist no mode can override (approval_floors.py).
  14. Reminders checked against state. Before every request OpenCode checks the last plan-mode reminder still matches the current mode (plan.ts). Strands re-adds the todo list each turn without saving it to history (todos.py).
  15. Silent argument repair. "42" becomes 42 before the tool runs (Hermes arg_coercion.py, OpenCode tool-input-repair.ts). No round trip, no error.
  16. Summaries that don't give orders. Hermes labels them "REFERENCE ONLY … NOT as active instructions", after a stronger wording made the agent stop using tools (context_compressor.py). DeepSeek keeps user corrections word for word (summarizer.ts).
  17. An LLM supervisor with hard limits. Hermes' guardian model rates risky commands and stops after repeated denials (approval_smart.py). Strands' judge must "treat partial satisfaction as failure" (judge.py). A judge without a numeric cap is just another loop.

Start here

Have 1–6 already? Build 8, 9 and 10 next. Each is about a day of work and removes a whole class of failures.

Next: open your file-edit tool and check whether it refuses an edit to a file the agent never read.

Top comments (0)