Harnesses
HarnessX: The harness foundry that makes agents evolvable
The same model produces dramatically different results depending on its harness. HarnessX makes that harness composable, searchable, and trainable — with GAIA benchmarks showing +14pp from harness evolution alone and +64% relative improvement from model-harness co-evolution.
- Published
- 13 Aug 2026
- Reading
- 14 min
- Class
- harnesses
half-life 90dfrom 13 Aug 2026
Ask any team why their agent failed in production and you'll hear about the model. The context window was too small. The reasoning wasn't deep enough. The model hallucinated a tool call.
Rarely do you hear: our harness couldn't recover from a rate limit, or our context compaction threw away the original goal, or we had no way to search for a better tool configuration.
Yet the harness — the loop, the context manager, the tool orchestrator, the error recovery, the evaluation feedback — is where the engineering actually lives. The model produces tokens; the harness decides what those tokens can touch, what happens when one is wrong, and what the model sees next. Two agents using the same model can differ by 20, 30, 50 percentage points on a benchmark purely because of harness differences.
HarnessX (MIT licensed, 430+ GitHub stars) is built on this insight. It's not another agent framework. It's a harness foundry: a system for forging, composing, searching, and evolving agent harnesses independently of the model. The core API is one line:
agent = model.agentic(harness)
ModelConfig handles provider routing, fallback, and per-role model assignment. HarnessConfig holds the entire behavior pipeline — tools, memory, processors, tracing, sandbox — completely separate. Swap the model, keep the harness. Swap the harness, keep the model. Compose new harnesses from reusable processors using the | operator. Run a meta-harness that searches the configuration space for you. Feed the resulting trajectories into RL training (via VERL) to improve the model itself.
This article walks through what HarnessX is, how its 9-dimension behavior pipeline works, the benchmark results that justify the architecture, and how to get started.
The 9-dimension behavior pipeline
HarnessX organizes all agent behavior into nine orthogonal dimensions, mapped to three pillars:
| # | Dimension | What It Controls | Module |
|---|---|---|---|
| 1 | Model Selection | Multi-provider routing + role assignment (main / judge / evaluator) | ModelConfig |
| 2 | Context Assembly | System prompt strategy + history truncation + user message wrapping | processors/context/ |
| 3 | Memory Management | Extract → Store → Retrieve with 5 pluggable strategies incl. Light-Memory | processors/memory/ |
| 4 | Tool Ecosystem | Built-in tools + MCP protocol + Skills + filtering | processors/tools/ + tools/ |
| 5 | Execution Environment | Sandbox isolation: Local / Docker / E2B cloud | sandbox/ |
| 6 | Evaluation & Reward | LLM Judge / SelfVerify / PRM / Benchmark evaluators | processors/evaluation/ |
| 7 | Control & Safety | 13 processors: loop detection, cost guard, compaction, sycophancy check | processors/control/ |
| 8 | Observability | HarnessJournal (JSONL) + OpenTelemetry + checkpoints + session recovery | processors/observability/ |
| 9 | Training Bridge | Trajectory → SFT / RL records with token-level annotations | rl/ |
Dimensions 1–5 (Compose) define what the agent can do. Dimensions 6–7 (Adapt) define how it corrects itself. Dimensions 8–9 (Evolve) define how it improves over time.
Every dimension is implemented as Processors that hook into 8 points in the event-driven run loop: on_start, on_user_message, on_model_request, on_model_response, on_tool_call, on_tool_result, on_turn_end, on_finish. Any behavior — context truncation, memory retrieval, tool filtering, cost guarding, trajectory logging — is a processor. You compose them with the | operator, and HarnessX does exhaustive conflict detection (singleton group collisions raise HarnessConflictError, no silent overwrites).
Code example: the core API
Here's a minimal runnable example showing the separation of model and harness:
import asyncio
from harnessx import BaseTask, HarnessConfig
from harnessx.core.model_config import ModelConfig
from harnessx.providers.anthropic_provider import AnthropicProvider
async def main():
# ModelConfig: provider routing, fallback, per-role assignment
model = ModelConfig(main=AnthropicProvider("claude-sonnet-4-6"))
# HarnessConfig: full behavior pipeline (tools, memory, processors, trace, sandbox)
harness = model.agentic(HarnessConfig())
result = await harness.run(BaseTask(description="What is 2 + 2?"))
print(result.final_output)
asyncio.run(main())
Now let's compose a coding harness with reliability processors:
from harnessx.bundles.coding import make_coding
from harnessx.bundles.reliability import make_reliability
# Compose bundles with the | operator — conflict detection is automatic
config = (make_coding(working_dir=".") | make_reliability()).build()
# HarnessConflictError if any singleton_group collides — no silent overwrites
model = ModelConfig(main=AnthropicProvider("claude-sonnet-4-6"))
harness = model.agentic(config)
result = await harness.run(BaseTask(description="Add a test for the login endpoint"))
The make_coding bundle brings in file tools, grep, ripgrep, LSP integration, and a context processor that keeps the codebase in view. make_reliability adds loop detection, cost guards, compaction, and sycophancy checks. They compose cleanly because each processor declares its singleton_group — HarnessX won't let two processors fight over the same hook.
Harness Evolution: searching the configuration space
The harness space is vast. With 7 processor categories, dozens of processors per category, and combinatorial composition, you're looking at ~106 valid configurations. Hand-tuning is guesswork.
HarnessX includes a Meta-Harness — an agent that observes its own trajectories, proposes harness configuration changes, and promotes improvements through a sandboxed evaluation loop. This is Harness Evolution: the harness improves itself without changing the model.
Results on the GAIA benchmark (reproducible via recipe/gaia_evolver/):
| Model | Baseline (R0) | After Evolution (R3) | Gain |
|---|---|---|---|
| Qwen 3.5 9B | 33% | 47% | +14pp |
| GPT-5 | 62% | 84% | +22pp |
The Qwen 3.5 9B run started from a default harness (33% on GAIA). The meta-harness discovered better processor combinations round by round — adding memory extraction, switching context strategies, tuning tool filters — reaching 47% by Round 3. Zero model changes. The same approach scales to frontier models: GPT-5 goes from 62% to 84%, with gains across all five GAIA domains.
Per-domain accuracy charts show the evolution isn't just lifting one category — it's systematic across web search, reasoning, fact-seeking, multi-hop, and tool use.
Model-Harness Co-Evolution: compounding gains
Harness Evolution improves the harness. But the trajectories it produces are also reward-annotated training data. HarnessX connects to VERL (Volcano Engine's RL training framework) for distributed PPO/GRPO training. This is Model Evolution.
Run both loops together and the gains compound:
| Stage | GAIA Accuracy (Qwen 3.5 9B) | Relative Improvement |
|---|---|---|
| Baseline harness (R0) | 33.97% | — |
| After Harness Evolution (R3) | 41.67% | +22.7% |
| After Model Evolution (RL) | 55.77% | +64% |
A 9B model reaching 55.77% on GAIA — surpassing many larger models — by evolving the harness first, then the model on top. The recipe/verl_harnessX/ directory contains the full training recipe: SGLang rollout adapter, token-level reward annotation, GRPO pipeline.
Key insight
Harness evolution is cheaper and faster than model training. Run it first. The improved harness produces better trajectories, which make model training more sample-efficient. The two loops compose: harness evolution → better data → better model → better harness → better data...
Getting started
Installation
One-click interactive install (asks before installing uv, Node.js, and optional IM Gateway):
curl -sSf https://raw.githubusercontent.com/Darwin-Agent/HarnessX/main/scripts/install.sh | bash
Non-interactive — install everything without prompts:
curl -sSf https://raw.githubusercontent.com/Darwin-Agent/HarnessX/main/scripts/install.sh | bash -s -- --all
Both commands install uv, Python 3.12, harnessx, and (with Node.js available) the Harness Lab frontend. After installation, reload your shell: source ~/.bashrc (or ~/.zshrc on macOS).
CLI (hx)
export ANTHROPIC_API_KEY=sk-...
hx "Research 2026 AI agent trends and write a structured report"
hx -p "Write a Python fizzbuzz" # non-interactive, print and exit
hx -c path/to/config.yaml # load a YAML config
hx --resume # resume a previous session
hx lab # open Lab UI at localhost:8000
The hx lab command launches the React + TypeScript Lab UI (built with Tailwind) — a visual interface for building, testing, and debugging harness configurations.
IM Gateway
Connect your agent to Feishu, Telegram, Slack, Discord, or DingTalk with a single service:
hx-gateway start # configured in ~/.harnessx/gateway.yaml
The gateway ships with a built-in React console for managing channels, sessions, and workspaces.
Python SDK
The minimal example above shows the core pattern. For production use, you'll want to explore:
- Bundles:
make_coding,make_reliability,make_research,make_assistant— pre-composed capability bundles - Custom processors: Subclass
Processorand register at any of the 8 hook points - Memory backends: Light-Memory (file-based, time-decay, daily compression, git versioning) or plug in SuperMemory, MemPalace, OpenVKing via the plugin system
- Sandboxes: Local (default), Docker, or E2B cloud for isolated code execution
Roadmap: where it's heading
HarnessX is in Phase 1 (core complete). The next phases are actively in progress:
| Phase | Focus | Status |
|---|---|---|
| 2 | Meta-opt: Bayesian Optimization, Meta-Harness, auto config search | In progress |
| 3 | Self-evolution: closed-loop training, HarnessHUB community marketplace | Planned |
| 4 | Memory: multimodal backends, third-party integrations (VERL, SuperMemory, OpenVKing) | Planned |
Notable in-repo implementations already working:
- Light-Memory — file-based memory with time-decay, daily compression, git versioning (
harnessx/plugins/dimensions/light_memory/) - Slime RL recipe — SGLang rollout adapter + token annotation + GRPO training pipeline (
recipe/slime/) - MetaHarness — agent observes its own trajectories and proposes harness config changes; observer harness + meta-agent + sandboxed promotion loop
The full ROADMAP has detailed design notes and motivation behind each item.
Why this matters for teams shipping agents
Most agent frameworks conflate the model and the harness. You pick a framework, you get its loop, its context strategy, its tool calling convention — and if that doesn't fit your use case, you fork or rewrite.
HarnessX takes the opposite bet: the harness should be data. Composable, versionable, searchable, trainable data. The model is a dependency you swap; the harness is the product you build.
For teams, this means:
- Faster iteration: Swap harness configurations via YAML, not code. Test 10 variants in the time it takes to rewrite one loop.
- Systematic improvement: Run the meta-harness overnight. Come back to a better configuration backed by benchmark numbers.
- Compound gains: Harness evolution produces the training data for model evolution. The flywheel is built in.
- Production hardening: 13 control processors (loop detection, cost guards, compaction, sycophancy checks) are off-the-shelf, not custom engineering.
- Observability by default: HarnessJournal (JSONL) + OpenTelemetry + checkpoints mean every run is replayable and debuggable.
The DA-195 article you're reading was written on a system that treats the harness as a first-class artifact. If you're building agents that need to run unattended, improve over time, or simply not fail in the same way twice, HarnessX is worth a serious look.
Resources
- GitHub: https://github.com/Darwin-Agent/HarnessX
- Homepage: https://raw.githack.com/Darwin-Agent/HarnessX/gh-pages/index.html
- Architecture docs: docs/architecture.md
- Roadmap: docs/ROADMAP.md
- GAIA evolution recipe: recipe/gaia_evolver/
- VERL co-evolution recipe: recipe/verl_harnessX/